Skip to content
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

Repo sync #35224

Merged
merged 5 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,86 @@ This SARIF output file has example values to show the minimum required propertie
}
```

### Relative URI Guidance for SARIF Producers

This SARIF output file has example of values for the field `originalUriBaseIds`, showing the minimum required properties a SARIF producer should include when using relative URI references.

{% note %}

**Note:** While this property is not required by {% data variables.product.prodname_dotcom %} for the {% data variables.product.prodname_code_scanning %} results to be displayed correctly, it is required to produce a valid SARIF output when using relative URI references.

{% endnote %}

```json
{
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
"version": "2.1.0",
"runs": [
{
"tool": {
"driver": {
"name": "Tool Name",
"rules": [
{
"id": "R01"
...
"properties" : {
"id" : "java/unsafe-deserialization",
"kind" : "path-problem",
"name" : "...",
"problem.severity" : "error",
"security-severity" : "9.8",
}
}
]
}
},
"originalUriBaseIds": {
"PROJECTROOT": {
"uri": "file:///C:/Users/Mary/code/TheProject/",
"description": {
"text": "The root directory for all project files."
}
},
"%SRCROOT%": {
"uri": "src/",
"uriBaseId": "PROJECTROOT",
"description": {
"text": "The root of the source tree."
}
}
},
"results": [
{
"ruleId": "R01",
"message": {
"text": "Result text. This result does not have a rule associated."
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "fileURI",
"uriBaseId": "%SRCROOT%"
},
"region": {
"startLine": 2,
"startColumn": 7,
"endColumn": 10
}
}
}
],
"partialFingerprints": {
"primaryLocationLineHash": "39fa2ee980eb94b0:1"
}
}
]
}
]
}
```

### Example showing all supported SARIF properties

This SARIF output file has example values to show all supported SARIF properties for {% data variables.product.prodname_code_scanning %}.
Expand Down
62 changes: 62 additions & 0 deletions src/frame/components/context/CategoryLandingContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import pick from 'lodash/pick'
import { createContext, useContext } from 'react'
import { LearningTrack } from './ArticleContext'
import {
FeaturedLink,
getFeaturedLinksFromReq,
} from 'src/landings/components/ProductLandingContext'

export type TocItem = {
fullPath: string
title: string
intro?: string
childTocItems?: Array<{
fullPath: string
title: string
intro: string
}>
}

export type CategoryLandingContextT = {
title: string
intro: string
productCallout: string
permissions: string
tocItems: Array<TocItem>
variant?: 'compact' | 'expanded'
featuredLinks: Record<string, Array<FeaturedLink>>
renderedPage: string
currentLearningTrack?: LearningTrack
currentLayout: string
}

export const CategoryLandingContext = createContext<CategoryLandingContextT | null>(null)

export const useCategoryLandingContext = (): CategoryLandingContextT => {
const context = useContext(CategoryLandingContext)

if (!context) {
throw new Error(
'"useCategoryLandingContext" may only be used inside "CategoryLandingContext.Provider"',
)
}

return context
}

export const getCategoryLandingContextFromRequest = (req: any): CategoryLandingContextT => {
return {
title: req.context.page.title,
productCallout: req.context.page.product || '',
permissions: req.context.page.permissions || '',
intro: req.context.page.intro,
tocItems: (req.context.genericTocFlat || req.context.genericTocNested || []).map((obj: any) =>
pick(obj, ['fullPath', 'title', 'intro', 'childTocItems']),
),
variant: req.context.genericTocFlat ? 'expanded' : 'compact',
featuredLinks: getFeaturedLinksFromReq(req),
renderedPage: req.context.renderedPage,
currentLearningTrack: req.context.currentLearningTrack,
currentLayout: req.context.currentLayoutName,
}
}
1 change: 1 addition & 0 deletions src/frame/lib/frontmatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const layoutNames = [
'product-guides',
'release-notes',
'inline',
'category-landing',
false,
]

Expand Down
14 changes: 11 additions & 3 deletions src/frame/middleware/context/generic-toc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import findPageInSiteTree from '@/frame/lib/find-page-in-site-tree.js'
export default async function genericToc(req: ExtendedRequest, res: Response, next: NextFunction) {
if (!req.context) throw new Error('request not contextualized')
if (!req.context.page) return next()
if (req.context.currentLayoutName !== 'default') return next()
if (
req.context.currentLayoutName !== 'default' &&
req.context.currentLayoutName !== 'category-landing'
)
return next()
// This middleware can only run on product, category, and map topics.
if (
req.context.page.documentType === 'homepage' ||
Expand Down Expand Up @@ -92,7 +96,7 @@ export default async function genericToc(req: ExtendedRequest, res: Response, ne
renderIntros = false
req.context.genericTocNested = await getTocItems(treePage, req.context, {
recurse: isRecursive,
renderIntros,
renderIntros: req.context.currentLayoutName === 'category-landing' ? true : false,
includeHidden,
})
}
Expand Down Expand Up @@ -127,7 +131,11 @@ async function getTocItems(node: Tree, context: Context, opts: Options): Promise
// Deliberately don't use `textOnly:true` here because we intend
// to display the intro, in a table of contents component,
// with the HTML (dangerouslySetInnerHTML).
intro = await page.renderProp('rawIntro', context)
intro = await page.renderProp(
'rawIntro',
context,
context.currentLayoutName === 'category-landing' ? { textOnly: true } : {},
)
}
}

Expand Down
67 changes: 67 additions & 0 deletions src/landings/components/CategoryLanding.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { useRouter } from 'next/router'
import cx from 'classnames'

import { useCategoryLandingContext } from 'src/frame/components/context/CategoryLandingContext'
import { DefaultLayout } from 'src/frame/components/DefaultLayout'
import { ArticleTitle } from 'src/frame/components/article/ArticleTitle'
import { Lead } from 'src/frame/components/ui/Lead'
import { ClientSideRedirects } from 'src/rest/components/ClientSideRedirects'
import { RestRedirect } from 'src/rest/components/RestRedirect'
import { Breadcrumbs } from 'src/frame/components/page-header/Breadcrumbs'

export const CategoryLanding = () => {
const router = useRouter()
const { title, intro, tocItems } = useCategoryLandingContext()

// tocItems contains directories and its children, we only want the child articles
const onlyFlatItems = tocItems.flatMap((item) => item.childTocItems || [])

return (
<DefaultLayout>
{router.route === '/[versionId]/rest/[category]' && <RestRedirect />}
{/* Doesn't matter *where* this is included because it will
never render anything. It always just return null. */}
<ClientSideRedirects />

<div className="container-xl px-3 px-md-6 my-4">
<div className={cx('d-none d-xl-block mt-3 mr-auto width-full')}>
<Breadcrumbs />
</div>
<ArticleTitle>{title}</ArticleTitle>

{intro && <Lead data-search="lead">{intro}</Lead>}

<h2 className="py-5">Spotlight</h2>
<div className="container-lg clearfix">
<div className="col-4 float-left border p-4">Spotlight 1</div>
<div className="col-4 float-left border p-4">Spotlight 2</div>
<div className="col-4 float-left border p-4">Spotlight 3</div>
</div>

<div className="pt-8">
<div className="py-5 clearfix border-bottom">
<div className="col-5 float-left p-3">
<h2>Explore {onlyFlatItems.length} prompt articles</h2>
</div>
<div className="col-3 float-left p-4">Searchbar</div>
<div className="col-1 float-left p-4">Category</div>
<div className="col-1 float-left p-4">Complexity</div>
<div className="col-1 float-left p-4">Industry</div>
<div className="col-1 float-left p-4">Reset</div>
</div>
<div className="clearfix gutter-md-spacious">
{/* TODO: replace with card components */}
{onlyFlatItems.map((item, index) => (
<div key={index} className="col-4 float-left p-4">
<div className="px-3 pb-3 border-bottom">
<div>{item.title}</div>
<div>{item.intro}</div>
</div>
</div>
))}
</div>
</div>
</div>
</DefaultLayout>
)
}
24 changes: 21 additions & 3 deletions src/landings/pages/product.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@ import { ArticlePage } from 'src/frame/components/article/ArticlePage'
import { ProductLanding } from 'src/landings/components/ProductLanding'
import { ProductGuides } from 'src/landings/components/ProductGuides'
import { TocLanding } from 'src/landings/components/TocLanding'
import { CategoryLanding } from 'src/landings/components/CategoryLanding'
import {
getTocLandingContextFromRequest,
TocLandingContext,
TocLandingContextT,
} from 'src/frame/components/context/TocLandingContext'
import {
getCategoryLandingContextFromRequest,
CategoryLandingContext,
CategoryLandingContextT,
} from 'src/frame/components/context/CategoryLandingContext'
import { useEffect } from 'react'

function initiateArticleScripts() {
Expand All @@ -54,13 +60,15 @@ type Props = {
productGuidesContext?: ProductGuidesContextT
tocLandingContext?: TocLandingContextT
articleContext?: ArticleContextT
categoryLandingContext?: CategoryLandingContextT
}
const GlobalPage = ({
mainContext,
productLandingContext,
productGuidesContext,
tocLandingContext,
articleContext,
categoryLandingContext,
}: Props) => {
const router = useRouter()

Expand All @@ -86,6 +94,12 @@ const GlobalPage = ({
<ProductGuides />
</ProductGuidesContext.Provider>
)
} else if (categoryLandingContext) {
content = (
<CategoryLandingContext.Provider value={categoryLandingContext}>
<CategoryLanding />
</CategoryLandingContext.Provider>
)
} else if (tocLandingContext) {
content = (
<TocLandingContext.Provider value={tocLandingContext}>
Expand Down Expand Up @@ -133,9 +147,13 @@ export const getServerSideProps: GetServerSideProps<Props> = async (context) =>
props.productGuidesContext = getProductGuidesContextFromRequest(req)
additionalUINamespaces.push('product_guides')
} else if (relativePath?.endsWith('index.md')) {
props.tocLandingContext = getTocLandingContextFromRequest(req)
if (props.tocLandingContext.currentLearningTrack?.trackName) {
additionalUINamespaces.push('learning_track_nav')
if (currentLayoutName === 'category-landing') {
props.categoryLandingContext = getCategoryLandingContextFromRequest(req)
} else {
props.tocLandingContext = getTocLandingContextFromRequest(req)
if (props.tocLandingContext.currentLearningTrack?.trackName) {
additionalUINamespaces.push('learning_track_nav')
}
}
} else if (props.mainContext.page) {
// All articles that might have hover cards needs this
Expand Down
5 changes: 5 additions & 0 deletions src/search/lib/elasticsearch-versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ for (const versionSource of Object.values(allVersions)) {
}
}

// Add the values to the keys as well so that the map value -> value works for versions that are already conformed to the indexVersion syntax
for (const [, value] of Object.entries(versionToIndexVersionMap)) {
versionToIndexVersionMap[value] = value
}

// All of the possible keys that can be input to access a version
export const allIndexVersionKeys = Array.from(
new Set([...Object.keys(versionToIndexVersionMap), ...Object.keys(allVersions)]),
Expand Down
Loading
Loading