Skip to content

Commit 93301e9

Browse files
committed
merge main into chore/remove-chainlink-components
2 parents 9ae57ea + 53682d4 commit 93301e9

23 files changed

Lines changed: 1276 additions & 1860 deletions

File tree

‎package-lock.json‎

Lines changed: 155 additions & 1700 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"sync-product-llms": "tsx src/scripts/sync-product-llms.ts",
2424
"validate:ccip-data": "tsx --require tsconfig-paths/register src/scripts/ccip/validate-directory-data.ts",
2525
"build": "NODE_OPTIONS=--max-old-space-size=8192 npm run build:pipeline",
26-
"build:pipeline": "npm run validate:ccip-data && npm run sync-product-llms && npm run generate:search-index && astro build && npm run pin-sol-version && node scripts/cleanup-vercel-function.mjs",
26+
"build:pipeline": "npm run validate:ccip-data && npm run sync-product-llms && npm run generate:search-index && astro build && npm run pin-sol-version && node scripts/cleanup-vercel-function.mjs && npm run check:swagger-assets",
2727
"preview": "astro preview",
2828
"pin-sol-version": "tsx --require tsconfig-paths/register src/scripts/helper/pin-solver-dist.ts",
2929
"linkcheckWrapper": "tsx --require tsconfig-paths/register src/scripts/link-check/linkcheckWrapper.ts",
@@ -67,6 +67,7 @@
6767
"quality-check": "npm run typecheck && npm run lint && npm run audit:exports",
6868
"quality-check:full": "npm run typecheck && npm run lint && npm run audit:dead-code",
6969
"generate:llms": "tsx --require tsconfig-paths/register src/scripts/generate-llms.ts",
70+
"check:swagger-assets": "tsx src/scripts/check-swagger-assets.ts",
7071
"check:llms": "tsx --require tsconfig-paths/register src/scripts/validate-llms.ts",
7172
"check:markdown-fidelity": "tsx --require tsconfig-paths/register src/scripts/check-markdown-fidelity.ts",
7273
"report:markdown-fidelity": "tsx --require tsconfig-paths/register src/scripts/check-markdown-fidelity.ts --publish --warn-only --omit-present"
@@ -134,13 +135,12 @@
134135
"preact": "^10.29.8",
135136
"react": "^19.3.1",
136137
"react-dom": "^19.3.1",
137-
"react-instantsearch": "^7.52.0",
138+
"react-instantsearch": "^7.54.0",
138139
"rehype-autolink-headings": "^7.1.0",
139140
"rehype-slug": "^6.0.0",
140141
"rehype-wrap-all": "^1.1.0",
141142
"remark-directive": "^3.0.1",
142-
"swagger-ui-dist": "^5.34.1",
143-
"swagger-ui-react": "^5.34.1",
143+
"swagger-ui-dist": "5.34.1",
144144
"tinyglobby": "^0.2.17",
145145
"tweetnacl": "^1.0.3",
146146
"uuid": "^11.1.1",
@@ -161,8 +161,6 @@
161161
"@types/prismjs": "^1.26.6",
162162
"@types/react": "^19.3.0",
163163
"@types/react-dom": "^19.3.0",
164-
"@types/swagger-ui-dist": "^3.30.6",
165-
"@types/swagger-ui-react": "^5.18.0",
166164
"@typescript-eslint/eslint-plugin": "^5.62.0",
167165
"@typescript-eslint/parser": "^5.62.0",
168166
"autoprefixer": "^10.6.2",
@@ -180,6 +178,7 @@
180178
"lint-staged": "^15.5.2",
181179
"node-fetch": "^2.7.0",
182180
"openapi-types": "^12.1.3",
181+
"parse5": "7.3.0",
183182
"patch-package": "^8.0.1",
184183
"path-to-regexp": "6.3.0",
185184
"pino-pretty": "^13.2.0",

‎public/licenses/swagger-ui-dist.txt‎

Lines changed: 406 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { describe, it, expect } from "@jest/globals"
2+
import { transformMarkdown } from "@lib/markdown/transformMarkdown.js"
3+
import { REQUIRED_ROLE_PRODUCTS, describeRequiredRole } from "./roles.js"
4+
5+
describe("describeRequiredRole", () => {
6+
it("names the role with its product and links to the product-scoped RBAC section", () => {
7+
expect(describeRequiredRole("ace", "operator")).toEqual({
8+
name: "ACE Operator",
9+
orHigher: true,
10+
url: "/chainlink-platform/rbac?parent=ace#ace",
11+
})
12+
})
13+
14+
it("does not say 'or higher' for the most privileged role", () => {
15+
expect(describeRequiredRole("ace", "admin")?.orHigher).toBe(false)
16+
expect(describeRequiredRole("cre", "admin")?.orHigher).toBe(false)
17+
})
18+
19+
it("uses the roles of each product", () => {
20+
expect(describeRequiredRole("cre", "developer")?.name).toBe("CRE Developer")
21+
expect(describeRequiredRole("crec", "operator")?.name).toBe("CRE Connect Operator")
22+
expect(describeRequiredRole("crec", "viewer")?.url).toBe("/chainlink-platform/rbac?parent=crec#cre-connect")
23+
})
24+
25+
it("returns null for an unknown product or role", () => {
26+
expect(describeRequiredRole("ace", "developer")).toBeNull()
27+
expect(describeRequiredRole("dataStreams", "admin")).toBeNull()
28+
expect(describeRequiredRole("toString", "admin")).toBeNull()
29+
expect(describeRequiredRole(undefined, "admin")).toBeNull()
30+
expect(describeRequiredRole("ace", 1)).toBeNull()
31+
})
32+
33+
it("lists the most privileged role first for every product", () => {
34+
for (const config of Object.values(REQUIRED_ROLE_PRODUCTS)) {
35+
expect(Object.keys(config.roles)[0]).toBe("admin")
36+
}
37+
})
38+
})
39+
40+
describe("RequiredRole in the Markdown export", () => {
41+
it("projects the role and the link as a sentence", async () => {
42+
const result = await transformMarkdown('<RequiredRole product="ace" role="operator" />', "/fake/path.mdx")
43+
expect(result).toContain("**Required role:** ACE Operator or higher.")
44+
expect(result).toContain("[What each role can do](/chainlink-platform/rbac?parent=ace#ace)")
45+
})
46+
47+
it("keeps the optional body after the sentence", async () => {
48+
const markdown = `<RequiredRole product="ace" role="admin">
49+
Creating a wallet needs the \`ace:core:wallet:write\` permission.
50+
</RequiredRole>`
51+
const result = await transformMarkdown(markdown, "/fake/path.mdx")
52+
expect(result).toContain("**Required role:** ACE Admin.")
53+
expect(result).not.toContain("ACE Admin or higher")
54+
expect(result).toContain("Creating a wallet needs the `ace:core:wallet:write` permission.")
55+
})
56+
57+
it("drops a component with an unknown role instead of leaking JSX", async () => {
58+
const result = await transformMarkdown(
59+
'Before\n\n<RequiredRole product="ace" role="owner" />\n\nAfter',
60+
"/fake/path.mdx"
61+
)
62+
expect(result).toContain("Before")
63+
expect(result).toContain("After")
64+
expect(result).not.toContain("RequiredRole")
65+
expect(result).not.toContain("Required role")
66+
})
67+
})
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import type { ReactNode } from "react"
2+
import { SvgArrowRight2, Tag, Typography, buttonVariants } from "@chainlink/blocks"
3+
import { describeRequiredRole, type RequiredRoleProduct } from "./roles.js"
4+
5+
interface RequiredRoleProps {
6+
product: RequiredRoleProduct
7+
role: string
8+
/** Optional short qualifier, for example the permission or a UI-only limit. */
9+
children?: ReactNode
10+
}
11+
12+
/**
13+
* Shows the role a reader needs to do what the page describes.
14+
*
15+
* Built only from @chainlink/blocks components and design tokens (no custom CSS), so it follows
16+
* the site theme, including dark mode, without extra work.
17+
*
18+
* Usage in MDX:
19+
*
20+
* import { RequiredRole } from "@components"
21+
*
22+
* <RequiredRole product="ace" role="operator" />
23+
*
24+
* <RequiredRole product="ace" role="admin">
25+
* Creating a wallet also needs the `ace:core:wallet:write` permission.
26+
* </RequiredRole>
27+
*
28+
* Role names and the link come from ./roles.ts. The link opens the shared RBAC page scoped to
29+
* the product, so the reader stays in that product's docs.
30+
*/
31+
export const RequiredRole = ({ product, role, children }: RequiredRoleProps) => {
32+
const info = describeRequiredRole(product, role)
33+
if (!info) {
34+
throw new Error(`<RequiredRole> does not know the role "${role}" for product "${product}". See roles.ts.`)
35+
}
36+
37+
return (
38+
<div
39+
role="note"
40+
aria-label="Required role"
41+
className="my-4 flex flex-col gap-2 rounded border border-solid border-border bg-muted p-4"
42+
>
43+
<div className="flex flex-wrap items-center gap-x-3 gap-y-2">
44+
<Typography variant="body-semi-xs" color="muted">
45+
Required role:
46+
</Typography>
47+
<Tag variant="progress" size="sm" hideIcon>
48+
{info.name}
49+
</Tag>
50+
{info.orHigher && <Typography variant="body-s">or higher</Typography>}
51+
<a
52+
href={info.url}
53+
className={`${buttonVariants({ variant: "tertiary", size: "xs", width: "hug" })} md:ml-auto`}
54+
>
55+
What each role can do
56+
<SvgArrowRight2 />
57+
</a>
58+
</div>
59+
{children && <div className="text-sm text-muted-foreground [&_p]:m-0 [&_p]:text-sm">{children}</div>}
60+
</div>
61+
)
62+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Roles per product, used by <RequiredRole>.
3+
*
4+
* This file is the single source of role names for the component. It is shared by the Astro
5+
* component and by the Markdown/LLM export, so both always say the same thing.
6+
*
7+
* - The product keys match the `?parent=` values of the shared Chainlink Platform pages.
8+
* - Roles are listed from the most to the least privileged. A role includes the permissions of
9+
* the roles below it, which is why the component says "or higher".
10+
* - Keep the labels and anchors in sync with /chainlink-platform/rbac.
11+
*/
12+
export const REQUIRED_ROLE_PRODUCTS = {
13+
ace: {
14+
label: "ACE",
15+
/** Heading id of the product section on /chainlink-platform/rbac. */
16+
anchor: "ace",
17+
roles: { admin: "Admin", operator: "Operator", viewer: "Viewer" },
18+
},
19+
crec: {
20+
label: "CRE Connect",
21+
anchor: "cre-connect",
22+
roles: { admin: "Admin", operator: "Operator", viewer: "Viewer" },
23+
},
24+
cre: {
25+
label: "CRE",
26+
anchor: "cre",
27+
roles: { admin: "Admin", developer: "Developer", viewer: "Viewer" },
28+
},
29+
} as const
30+
31+
export type RequiredRoleProduct = keyof typeof REQUIRED_ROLE_PRODUCTS
32+
33+
export interface RequiredRoleDescription {
34+
/** Full role name, for example "ACE Operator". */
35+
name: string
36+
/** True when higher roles also qualify, which is every role except the most privileged. */
37+
orHigher: boolean
38+
/** Link to the role reference, scoped to the product so the reader stays in its docs. */
39+
url: string
40+
}
41+
42+
/**
43+
* Resolves a product and role key to the text shown to the reader.
44+
* Returns null for an unknown product or role, so callers can fail loudly.
45+
*/
46+
export function describeRequiredRole(product: unknown, role: unknown): RequiredRoleDescription | null {
47+
if (typeof product !== "string" || typeof role !== "string") return null
48+
if (!Object.hasOwn(REQUIRED_ROLE_PRODUCTS, product)) return null
49+
50+
const config = REQUIRED_ROLE_PRODUCTS[product as RequiredRoleProduct]
51+
const roleKeys: string[] = Object.keys(config.roles)
52+
const index = roleKeys.indexOf(role)
53+
if (index === -1) return null
54+
55+
const roleLabel = (config.roles as Record<string, string>)[role]
56+
return {
57+
name: `${config.label} ${roleLabel}`,
58+
orHigher: index > 0,
59+
url: `/chainlink-platform/rbac?parent=${product}#${config.anchor}`,
60+
}
61+
}

‎src/components/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export { CopyPageLink } from "./RightSidebar/CopyPageLink"
1414
export { default as Aside } from "./Aside.astro"
1515
export { default as ProductSection } from "./ProductSection.astro"
1616
export { default as ProductOnly } from "./ProductOnly.astro"
17+
export { RequiredRole } from "./RequiredRole/RequiredRole.tsx"
1718
export { default as ReleaseNotes } from "./ReleaseNotes.astro"
1819
export { default as Icon } from "./Icon.astro"
1920
export { default as ClickToZoom } from "./ClickToZoom.astro"

‎src/config/data/ccip/v1_2_0/testnet/chains.json‎

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -976,30 +976,6 @@
976976
"version": "1.5.1"
977977
}
978978
},
979-
"janction-testnet-sepolia": {
980-
"armProxy": {
981-
"address": "0x2b78139A0580592e2dfa55138c1F2eA5376b1ab4",
982-
"version": "1.0.0"
983-
},
984-
"chainSelector": "5059197667603797935",
985-
"feeTokens": [],
986-
"registryModule": {
987-
"address": "0x95964Bf01b642Ce6Aa8996cC517B9a140fEb1E9f",
988-
"version": "1.5.0"
989-
},
990-
"router": {
991-
"address": "0x6ddAFdf8bA76AFED73d6e7B599adDE014fA293bC",
992-
"version": "1.2.0"
993-
},
994-
"tokenAdminRegistry": {
995-
"address": "0x869D08b51D16869899d16a0Ba3eAda58521f8854",
996-
"version": "1.5.0"
997-
},
998-
"tokenPoolFactory": {
999-
"address": "0x053F1947Bb2e69a73C06276c8ec5859D61619857",
1000-
"version": "1.5.1"
1001-
}
1002-
},
1003979
"jovay-testnet": {
1004980
"armProxy": {
1005981
"address": "0x5Dc49Ec54B92F7D493bC8126c0730DA74605cc00",
@@ -1246,7 +1222,7 @@
12461222
"version": "1.0.0"
12471223
},
12481224
"chainSelector": "6955638871347136141",
1249-
"feeTokens": ["LINK", "WSBY"],
1225+
"feeTokens": [],
12501226
"registryModule": {
12511227
"address": "0xB6bD6e3e56a8E28CCbE44b6442cA8b586B964Af8",
12521228
"version": "1.6.0"

‎src/config/data/ccip/v1_2_0/testnet/decom.json‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,8 @@
8282
},
8383
"superseed-testnet": {
8484
"chainSelector": "13694007683517087973"
85+
},
86+
"polkadot-testnet-astar-shibuya": {
87+
"chainSelector": "6955638871347136141"
8588
}
8689
}

0 commit comments

Comments
 (0)