construct-hub 0.3.157 → 0.3.161

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. package/.jsii +2 -2
  2. package/lib/construct-hub.js +1 -1
  3. package/lib/package-sources/code-artifact.js +1 -1
  4. package/lib/package-sources/npmjs.js +1 -1
  5. package/lib/package-tag/index.js +2 -2
  6. package/lib/s3/storage.js +1 -1
  7. package/lib/spdx-license.js +1 -1
  8. package/package.json +4 -7
  9. package/website/asset-manifest.json +24 -24
  10. package/website/index.html +1 -1
  11. package/website/static/js/11.ac7ee4e8.chunk.js +2 -0
  12. package/website/static/js/11.ac7ee4e8.chunk.js.map +1 -0
  13. package/website/static/js/{12.5f44f9cb.chunk.js → 12.7c6d5a9b.chunk.js} +2 -2
  14. package/website/static/js/{12.5f44f9cb.chunk.js.map → 12.7c6d5a9b.chunk.js.map} +1 -1
  15. package/website/static/js/{13.edbebe8c.chunk.js → 13.154f7765.chunk.js} +2 -2
  16. package/website/static/js/{13.edbebe8c.chunk.js.map → 13.154f7765.chunk.js.map} +1 -1
  17. package/website/static/js/{14.be59e36b.chunk.js → 14.cb53c7d1.chunk.js} +2 -2
  18. package/website/static/js/{14.be59e36b.chunk.js.map → 14.cb53c7d1.chunk.js.map} +1 -1
  19. package/website/static/js/{5.a4f881bb.chunk.js → 5.a110843d.chunk.js} +3 -3
  20. package/website/static/js/{5.a4f881bb.chunk.js.LICENSE.txt → 5.a110843d.chunk.js.LICENSE.txt} +0 -0
  21. package/website/static/js/{5.a4f881bb.chunk.js.map → 5.a110843d.chunk.js.map} +1 -1
  22. package/website/static/js/{6.37c76213.chunk.js → 6.8944c773.chunk.js} +2 -2
  23. package/website/static/js/{6.37c76213.chunk.js.map → 6.8944c773.chunk.js.map} +1 -1
  24. package/website/static/js/{7.868cb67c.chunk.js → 7.80720b8b.chunk.js} +2 -2
  25. package/website/static/js/{7.868cb67c.chunk.js.map → 7.80720b8b.chunk.js.map} +1 -1
  26. package/website/static/js/8.e4b13e68.chunk.js +2 -0
  27. package/website/static/js/8.e4b13e68.chunk.js.map +1 -0
  28. package/website/static/js/main.ded71e5d.chunk.js +2 -0
  29. package/website/static/js/main.ded71e5d.chunk.js.map +1 -0
  30. package/website/static/js/runtime-main.e4632d3a.js +2 -0
  31. package/website/static/js/{runtime-main.1d84ea40.js.map → runtime-main.e4632d3a.js.map} +1 -1
  32. package/website/static/js/11.03c1b5c2.chunk.js +0 -2
  33. package/website/static/js/11.03c1b5c2.chunk.js.map +0 -1
  34. package/website/static/js/8.ddcecc46.chunk.js +0 -2
  35. package/website/static/js/8.ddcecc46.chunk.js.map +0 -1
  36. package/website/static/js/main.b05b661e.chunk.js +0 -2
  37. package/website/static/js/main.b05b661e.chunk.js.map +0 -1
  38. package/website/static/js/runtime-main.1d84ea40.js +0 -2
@@ -1,2 +0,0 @@
1
- (this["webpackJsonpconstruct-hub-webapp"]=this["webpackJsonpconstruct-hub-webapp"]||[]).push([[11],{208:function(e,t,r){"use strict";r.d(t,"a",(function(){return c}));var s=r(0),i=r(225),n={contribute:{event:{name:"Contribute Load"}},home:{event:{name:"Home Load"}},faq:{event:{name:"Frequently Asked Questions Load"}},packageProfile:{event:{name:"Package Profile Load"}},search:{event:{name:"Search Load"}},siteTerms:{event:{name:"Site Terms Load"}},notFound:{page:{pageType:"errorPage"},event:{name:"404 Page Load"}}},a=r(34),o=r(2),c=(["default-src 'self' 'unsafe-inline' http://*.awsstatic.com;","connect-src 'self' https://*.shortbread.aws.dev http://*.shortbread.aws.dev http://a0.awsstatic.com/ http://amazonwebservices.d2.sc.omtrdc.net http://aws.demdex.net http://dpm.demdex.net http://cm.everesttech.net;","frame-src http://aws.demdex.net http://dpm.demdex.net;","img-src 'self' https://* http://a0.awsstatic.com/ http://amazonwebservices.d2.sc.omtrdc.net http://aws.demdex.net http://dpm.demdex.net http://cm.everesttech.net;","object-src 'none';","style-src 'self' 'unsafe-inline';"].join(" "),function(e){var t=e.children,r=e.meta,c=e.pageName,l=Object(a.d)(n[c]);Object(s.useEffect)((function(){l()}),[l]);var u=r.suffix,d=void 0===u||u,h=r.title,b=r.description,p=d?"".concat(h," - Construct Hub"):h;return Object(o.jsxs)(o.Fragment,{children:[Object(o.jsxs)(i.a,{children:[!1,Object(o.jsx)("meta",{content:"width=device-width, initial-scale=1",name:"viewport"}),Object(o.jsx)("meta",{charSet:"utf-8"}),Object(o.jsx)("title",{children:p}),Object(o.jsx)("meta",{content:p,property:"og:title"}),Object(o.jsx)("meta",{content:p,name:"twitter:title"}),Object(o.jsx)("meta",{content:"summary",name:"twitter:card"}),Object(o.jsx)("meta",{content:b,name:"description"}),Object(o.jsx)("meta",{content:b,property:"og:description"}),Object(o.jsx)("meta",{content:b,name:"twitter:description"})]}),t]})})},296:function(e,t,r){"use strict";r.d(t,"a",(function(){return n})),r.d(t,"b",(function(){return a})),r.d(t,"c",(function(){return c})),r.d(t,"d",(function(){return u})),r.d(t,"e",(function(){return d})),r.d(t,"f",(function(){return j}));var s=r(124),i=r(2),n=function(e){var t=e.children;return Object(i.jsxs)(s.b,{bg:"white",color:"blue.800",h:"100%",w:"100%",children:[t,Object(i.jsx)(s.b,{py:5,width:"100%"})]})},a=function(e){var t=e.children;return Object(i.jsx)(s.b,{bg:"gray.50",py:20,width:"100%",children:Object(i.jsx)(s.i,{as:"h1",mx:"auto",textAlign:"center",children:t})})},o=r(131),c=function(e){var t=e.question,r=e.children;return Object(i.jsxs)(o.d,{children:[Object(i.jsxs)(o.b,{children:[Object(i.jsx)(s.b,{flex:"1",py:2,textAlign:"left",children:Object(i.jsx)(s.i,{as:"h3",ml:8,size:"sm",children:t})}),Object(i.jsx)(o.c,{})]}),Object(i.jsx)(o.e,{px:12,py:4,children:Object(i.jsx)(s.q,{color:"blue.800",fontSize:"md",sx:{p:{marginTop:"0",marginBottom:"4"}},children:r})})]})},l=r(57),u=function(e){var t=e.href,r=e.children;return Object(i.jsx)(l.a,{color:"inherit",hasWarning:!1,href:t,textDecoration:"underline",children:r})},d=function(e){var t=e.heading,r=e.children;return Object(i.jsxs)(o.d,{children:[Object(i.jsxs)(o.b,{children:[Object(i.jsx)(s.b,{flex:"1",textAlign:"left",children:Object(i.jsx)(s.i,{as:"h2",ml:4,my:4,size:"lg",children:t})}),Object(i.jsx)(o.c,{})]}),Object(i.jsx)(o.e,{p:0,children:Object(i.jsx)(o.a,{allowMultiple:!0,w:"100%",children:r})})]})},h=r(6),b=r(21),p=["children"],j=function(e){var t=e.children,r=Object(b.a)(e,p);return Object(i.jsx)(o.a,Object(h.a)(Object(h.a)({allowMultiple:!0},r),{},{children:t}))}},601:function(e,t,r){"use strict";r.r(t),r.d(t,"default",(function(){return l}));var s=r(131),i=r(124),n=r(296),a=r(208),o=r(64),c=r(2),l=function(){return Object(c.jsx)(a.a,{meta:{description:"Learn about contributing to Construct Hub.",title:"Contribute"},pageName:"contribute",children:Object(c.jsxs)(n.a,{children:[Object(c.jsx)(n.b,{children:"Contributing to Construct Hub"}),Object(c.jsxs)(s.a,{allowMultiple:!0,allowToggle:!0,defaultIndex:[0],children:[Object(c.jsxs)(n.c,{question:"How can I add my construct to Construct Hub?",children:[Object(c.jsxs)(i.q,{children:["Constructs intended for Construct Hub must be published to the"," ",Object(c.jsx)(n.d,{href:"https://www.npmjs.com/",children:"npm Registry"})," under Apache, BSD, EPL, MPL-2.0, ISC and CDDL or MIT open source licenses and annotated with a keyword recognized by Construct Hub (awscdk, cdk8s, or cdktf)."]}),Object(c.jsxs)(i.q,{children:["Additionally, since one of the main goals of Construct Hub is to enable an ecosystem of constructs that can be consumed by all CDK languages, your library ",Object(c.jsx)("strong",{children:"must"})," be compiled with"," ",Object(c.jsx)(n.d,{href:"https://aws.github.io/jsii/",children:"JSII"}),", a TypeScript-based tool for building multi-language libraries. Construct Hub leverages the type information produced by the JSII compiler to render a rich multi-language API reference for each construct."]}),Object(c.jsxs)(i.q,{children:["Construct Hub continuously monitors the npm Registry. Packages that meet the above requirements appear in Construct Hub in about 30 minutes. If your package does not appear in Construct Hub, but meets these requirements, please file an issue against our"," ",Object(c.jsx)(n.d,{href:"".concat(o.a,"/issues/new"),children:"GitHub repository."})]}),Object(c.jsxs)(i.q,{children:["The community has provided some great resources about publishing construct libraries that meet Construct Hub requirements. For example, see"," ",Object(c.jsxs)(n.d,{href:"https://dev.to/aws-builders/a-beginner-s-guide-to-create-aws-cdk-construct-library-with-projen-5eh4",children:["\u201cA Beginner's Guide to Create AWS CDK ConstructLibrary with"," ","projen\u201d"]})," ","by ",Object(c.jsx)(n.d,{href:"https://hayao-k.dev/",children:"hayao-k"}),"."]}),Object(c.jsxs)(i.q,{children:["If you already have a library written in TypeScript and want to migrate it to JSII so it can be included in Construct Hub, see the"," ",Object(c.jsx)(n.d,{href:"https://aws.github.io/jsii/user-guides/#library-author-guide",children:"JSII library author guide."})]})]}),Object(c.jsxs)(n.c,{question:"What are the best practices for improving discoverability of a construct library on Construct Hub?",children:[Object(c.jsx)(i.q,{children:"To improve your construct library\u2019s visibility on Construct Hub, follow these best practices:"}),Object(c.jsxs)(i.n,{sx:{li:{mt:4}},children:[Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Helpful description."})," Publish your library with a description. Libraries without description have lower chances to be discovered by users. When you write your library\u2019s description, think: Why would someone use it? What makes it unique? Make the description as accurate and differentiated as possible."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Helpful keywords."})," Publish your library with helpful keywords, ones that can help potential users to find your package. Helpful keywords can be technologies that are being used by the library, use cases the library is useful for, service names that are being used by the library etc. For example: \u2018Monitoring\u2019, \u2018Kubernetes\u2019, \u2018Cost Management\u2019, \u2018Websites\u2019, \u2018AI\u2019, \u2018Containers\u2019 and more."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Helpful keywords."})," Publish your library with helpful keywords, ones that can help potential users to find your package. Helpful keywords can be technologies that are being used by the library, use cases the library is useful for, service names that are being used by the library etc. For example: \u2018Monitoring\u2019, \u2018Kubernetes\u2019, \u2018Cost Management\u2019, \u2018Websites\u2019, \u2018AI\u2019, \u2018Containers\u2019 and more."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Helpful README."})," Review your library\u2019s README file. Is it developer-friendly? That is, can developers quickly understand the use case you\u2019re trying to solve? Does your README make it easy to get started with your library? Does it explain how your library is different from other libraries? Is it easy to understand at first glance the value developers gain from the library? For more information see *\u201cQ: What are the best practices for a developer-friendly README file?\u201d.*"]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"API documentation."})," Document the library classes, methods, properties in the library\u2019s code. Construct Hub will display this information when it automatically generates the API documentation."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Maintain your library."})," Developers prefer libraries that are updated on a regular basis. Our experience shows that successful libraries are those where publishers engage and collaborate with the user community, respond to issues and pull requests, fix bugs, and add capabilities. To gain more developers trust, maintain the releases section on your code repository and make sure to describe the changes between different releases. You may consider to link the libraries you\u2019ve published with your code repository."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"AWS Partner Network (APN) badge."})," If you\u2019re an AWS partner and you are publishing a library for your offering, please reach out to us and we will be happy to add a badge to your libraries with your company\u2019s name."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Enable support for multiple programming languages."})," ","Make your library usable by a broader set of users and increase its value to the ecosystem. Starting with your library written in TypeScript, JSII will create packages in the other CDK programming languages. Construct Hub will then automatically generate API reference and transliterate code samples. All you need to do is to follow the instructions under *\u201cQ: How can I add my construct to Construct Hub?\u201d.*"]})]})]}),Object(c.jsxs)(n.c,{question:"What are the best practices for writing a developer-friendly README file?",children:[Object(c.jsx)(i.q,{children:"Developer-friendly READMEs help readers quickly understand your library\u2019s relevance to their needs and its unique value in comparison to similar libraries on the Construct Hub. Below is a suggestion for a README file structure:"}),Object(c.jsxs)(i.r,{sx:{li:{mt:4}},children:[Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"State and maturity of the library."})," Start your READMEs with helpful badges like"," ",Object(c.jsx)(n.d,{href:"https://www.npmjs.com/package/cdk-codepipeline-badge-notification",children:"CDK pipelines badges"}),". It will help users see the state of your package."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Short description"}),". What does this library do? Which use case does it solve? Which technologies and services does it use or support?"]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"What is unique about this library?"})," Help readers quickly find the right library for their needs by stating its special advantages right up front. How does it compare to other libraries addressing the same need or that use the same technologies and services? You don\u2019t need an explicit \u201cus vs. them\u201d feature checklist; just make sure you communicate your library\u2019s unique value."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Code samples."})," Include as many complete and working code samples as you can to help developers quickly understand how they can use your library. Some developers start reading code samples before anything else. Write your code samples in TypeScript, and Construct Hub will transliterate them to the other programming languages your library supports. A good practice is to include a minimal code sample of how to use your library in the first page of your README."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Author information."})," Share information about you, other packages you\u2019ve published, and additional helpful links that can improve your credibility with readers."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"License and support."})," Include a \u201cLicense\u201d and \u201cContributing\u201d sections that invite users to contribute via links to your source code repository and issue tracker. (Construct Hub provides \u201cLicense\u201d and \u201cProvide Feedback\u201d in your library\u2019s package page, but it\u2019s convenient to have them in the README too.)"]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Diagrams."})," Diagrams always help readers quickly understand what a library does. Consider adding diagrams for libraries that create multiple services that work together."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Explanatory videos."})," Consider sharing links to videos that can help potential customers engage with your library."]}),Object(c.jsxs)(i.m,{children:[Object(c.jsx)("strong",{children:"Absolute links vs. relative."})," Use absolute links (those that start with http:// or https://) and not relative links. Relative links are prone to breaking when the content is shared elsewhere."]})]})]}),Object(c.jsx)(n.c,{question:"Why isn\u2019t my package displayed on Construct Hub?",children:Object(c.jsxs)(i.q,{children:["Construct Hub includes publicly-available constructs that are JSII-compatible and that were published to the npm Registry with a permissive open-source license and a CDK keyword: aws-cdk, cdk8s, or cdktf. If you believe your package qualifies, but it still does not appear in Construct Hub, please raise an issue"," ",Object(c.jsx)(n.d,{href:"".concat(o.a,"/issues/new"),children:"here"}),"."]})}),Object(c.jsx)(n.c,{question:"Can I update my package after it has been displayed?",children:Object(c.jsx)(i.q,{children:"Yes, you can and should! After you publish a new valid version to the public npm Registry, it should appear on Construct Hub in about 30 minutes."})}),Object(c.jsx)(n.c,{question:"How can I report a bug or contribute code to a construct?",children:Object(c.jsx)(i.q,{children:"Each package is owned by its publisher, so contributions, such as bug reports and pull requests, should be made via the repository link provided by the publisher. You may press the \u2018Provide feedback\u2019 link at the package page to open a new issue in at the package\u2019s repository."})}),Object(c.jsxs)(n.c,{question:"How can I participate in link the Construct Hub community?",children:["Construct Hub is itself an open-source construct! Join the"," ",Object(c.jsx)(n.d,{href:"https://github.com/cdklabs/construct-hub",children:"Construct Hub GitHub community"}),". You are also welcome to join the #construct-hub-dev channel in the"," ",Object(c.jsx)(n.d,{href:"https://cdk.dev/",children:"CDK community Slack workspace"})]}),Object(c.jsx)(n.c,{question:"Is there a Slack channel for the CDK community?",children:Object(c.jsxs)(i.q,{children:["Please join the"," ",Object(c.jsx)(n.d,{href:"https://cdk.dev/",children:"CDK Slack channel"}),". This Slack channel is managed by the CDK community, for the CDK community."]})})]})]})})}}}]);
2
- //# sourceMappingURL=11.03c1b5c2.chunk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["constants/pageInfo.ts","components/Page/Page.tsx","components/FAQ/FAQ.tsx","components/FAQ/FAQHeading.tsx","components/FAQ/FAQItem.tsx","components/FAQ/FAQLink.tsx","components/FAQ/FAQSection.tsx","components/FAQ/FAQSections.tsx","views/Contribute/Contribute.tsx"],"names":["pageInfo","contribute","event","name","home","faq","packageProfile","search","siteTerms","notFound","page","pageType","Page","join","children","meta","pageName","trackPageView","usePageView","useEffect","suffix","title","description","formattedTitle","Helmet","process","content","charSet","property","FAQ","bg","color","h","w","py","width","FAQHeading","as","mx","textAlign","FAQItem","question","flex","ml","size","px","fontSize","sx","p","marginTop","marginBottom","FAQLink","href","ExternalLink","hasWarning","textDecoration","FAQSection","heading","my","allowMultiple","FAQSections","accordionProps","Contribute","allowToggle","defaultIndex","CONSTRUCT_HUB_REPO_URL","li","mt"],"mappings":"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","file":"static/js/11.03c1b5c2.chunk.js","sourcesContent":["export const pageInfo = {\n contribute: {\n event: {\n name: \"Contribute Load\",\n },\n },\n home: {\n event: {\n name: \"Home Load\",\n },\n },\n faq: {\n event: {\n name: \"Frequently Asked Questions Load\",\n },\n },\n packageProfile: {\n event: {\n name: \"Package Profile Load\",\n },\n },\n search: {\n event: {\n name: \"Search Load\",\n },\n },\n siteTerms: {\n event: {\n name: \"Site Terms Load\",\n },\n },\n notFound: {\n page: {\n pageType: \"errorPage\",\n },\n event: {\n name: \"404 Page Load\",\n },\n },\n} as const;\n","import { FunctionComponent, useEffect } from \"react\";\nimport { Helmet } from \"react-helmet\";\nimport { pageInfo } from \"../../constants/pageInfo\";\nimport { usePageView } from \"../../contexts/Analytics\";\n\nexport interface PageProps {\n pageName: keyof typeof pageInfo;\n meta: {\n suffix?: boolean;\n title: string;\n description: string;\n };\n}\n\n// Should be the same as the \"real\" CSP, except most things come from HTTP\n// instead of HTTPS (because it is protocol-relative, and the dev site is\n// served over plain HTTP).\nconst csp = [\n \"default-src 'self' 'unsafe-inline' http://*.awsstatic.com;\",\n \"connect-src 'self' https://*.shortbread.aws.dev http://*.shortbread.aws.dev http://a0.awsstatic.com/ http://amazonwebservices.d2.sc.omtrdc.net http://aws.demdex.net http://dpm.demdex.net http://cm.everesttech.net;\",\n \"frame-src http://aws.demdex.net http://dpm.demdex.net;\",\n \"img-src 'self' https://* http://a0.awsstatic.com/ http://amazonwebservices.d2.sc.omtrdc.net http://aws.demdex.net http://dpm.demdex.net http://cm.everesttech.net;\",\n \"object-src 'none';\",\n \"style-src 'self' 'unsafe-inline';\",\n].join(\" \");\n\nexport const Page: FunctionComponent<PageProps> = ({\n children,\n meta,\n pageName,\n}) => {\n const trackPageView = usePageView(pageInfo[pageName]);\n\n useEffect(() => {\n trackPageView();\n }, [trackPageView]);\n\n const { suffix = true, title, description } = meta;\n const formattedTitle = suffix ? `${title} - Construct Hub` : title;\n\n return (\n <>\n <Helmet>\n {process.env.NODE_ENV === \"development\" && (\n <meta content={csp} httpEquiv=\"Content-Security-Policy\" />\n )}\n\n <meta content=\"width=device-width, initial-scale=1\" name=\"viewport\" />\n <meta charSet=\"utf-8\" />\n\n <title>{formattedTitle}</title>\n <meta content={formattedTitle} property=\"og:title\" />\n <meta content={formattedTitle} name=\"twitter:title\" />\n <meta content=\"summary\" name=\"twitter:card\" />\n\n <meta content={description} name=\"description\" />\n <meta content={description} property=\"og:description\" />\n <meta content={description} name=\"twitter:description\" />\n </Helmet>\n {children}\n </>\n );\n};\n","import { Box } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\n\nexport const FAQ: FunctionComponent = ({ children }) => (\n <Box bg=\"white\" color=\"blue.800\" h=\"100%\" w=\"100%\">\n {children}\n <Box py={5} width=\"100%\" />\n </Box>\n);\n","import { Box, Heading } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\n\nexport const FAQHeading: FunctionComponent = ({ children }) => (\n <Box bg=\"gray.50\" py={20} width=\"100%\">\n <Heading as=\"h1\" mx=\"auto\" textAlign=\"center\">\n {children}\n </Heading>\n </Box>\n);\n","import {\n Heading,\n Text,\n AccordionIcon,\n AccordionButton,\n AccordionItem,\n AccordionPanel,\n Box,\n} from \"@chakra-ui/react\";\nimport type { FunctionComponent, ReactChild } from \"react\";\n\nexport interface FAQItemProps {\n question: ReactChild;\n}\n\nexport const FAQItem: FunctionComponent<FAQItemProps> = ({\n question,\n children,\n}) => (\n <AccordionItem>\n <AccordionButton>\n <Box flex=\"1\" py={2} textAlign=\"left\">\n <Heading as=\"h3\" ml={8} size=\"sm\">\n {question}\n </Heading>\n </Box>\n <AccordionIcon />\n </AccordionButton>\n <AccordionPanel px={12} py={4}>\n <Text\n color=\"blue.800\"\n fontSize=\"md\"\n sx={{ p: { marginTop: \"0\", marginBottom: \"4\" } }}\n >\n {children}\n </Text>\n </AccordionPanel>\n </AccordionItem>\n);\n","import { FunctionComponent } from \"react\";\nimport { ExternalLink } from \"../../components/ExternalLink\";\n\nexport interface FAQLinkProps {\n href: string;\n}\n\nexport const FAQLink: FunctionComponent<FAQLinkProps> = ({\n href,\n children,\n}) => (\n <ExternalLink\n color=\"inherit\"\n hasWarning={false}\n href={href}\n textDecoration=\"underline\"\n >\n {children}\n </ExternalLink>\n);\n","import {\n AccordionIcon,\n AccordionButton,\n AccordionItem,\n AccordionPanel,\n Heading,\n Box,\n Accordion,\n} from \"@chakra-ui/react\";\n\nimport type { FunctionComponent } from \"react\";\n\nexport interface FAQSectionProps {\n heading: string;\n}\n\nexport const FAQSection: FunctionComponent<FAQSectionProps> = ({\n heading,\n children,\n}) => (\n <AccordionItem>\n <AccordionButton>\n <Box flex=\"1\" textAlign=\"left\">\n <Heading as=\"h2\" ml={4} my={4} size=\"lg\">\n {heading}\n </Heading>\n </Box>\n <AccordionIcon />\n </AccordionButton>\n <AccordionPanel p={0}>\n <Accordion allowMultiple w=\"100%\">\n {children}\n </Accordion>\n </AccordionPanel>\n </AccordionItem>\n);\n","import { Accordion, AccordionProps } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\n\nexport const FAQSections: FunctionComponent<AccordionProps> = ({\n children,\n ...accordionProps\n}) => (\n <Accordion allowMultiple {...accordionProps}>\n {children}\n </Accordion>\n);\n","import {\n Accordion,\n OrderedList,\n ListItem,\n Text,\n UnorderedList,\n} from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { FAQ, FAQHeading, FAQItem, FAQLink } from \"../../components/FAQ\";\nimport { Page } from \"../../components/Page\";\nimport { CONSTRUCT_HUB_REPO_URL } from \"../../constants/links\";\n\nexport const Contribute: FunctionComponent = () => (\n <Page\n meta={{\n description: \"Learn about contributing to Construct Hub.\",\n title: \"Contribute\",\n }}\n pageName=\"contribute\"\n >\n <FAQ>\n <FAQHeading>Contributing to Construct Hub</FAQHeading>\n\n <Accordion allowMultiple allowToggle defaultIndex={[0]}>\n <FAQItem question=\"How can I add my construct to Construct Hub?\">\n <Text>\n Constructs intended for Construct Hub must be published to the{\" \"}\n <FAQLink href=\"https://www.npmjs.com/\">npm Registry</FAQLink> under\n Apache, BSD, EPL, MPL-2.0, ISC and CDDL or MIT open source licenses\n and annotated with a keyword recognized by Construct Hub (awscdk,\n cdk8s, or cdktf).\n </Text>\n\n <Text>\n Additionally, since one of the main goals of Construct Hub is to\n enable an ecosystem of constructs that can be consumed by all CDK\n languages, your library <strong>must</strong> be compiled with{\" \"}\n <FAQLink href=\"https://aws.github.io/jsii/\">JSII</FAQLink>, a\n TypeScript-based tool for building multi-language libraries.\n Construct Hub leverages the type information produced by the JSII\n compiler to render a rich multi-language API reference for each\n construct.\n </Text>\n\n <Text>\n Construct Hub continuously monitors the npm Registry. Packages that\n meet the above requirements appear in Construct Hub in about 30\n minutes. If your package does not appear in Construct Hub, but meets\n these requirements, please file an issue against our{\" \"}\n <FAQLink href={`${CONSTRUCT_HUB_REPO_URL}/issues/new`}>\n GitHub repository.\n </FAQLink>\n </Text>\n\n <Text>\n The community has provided some great resources about publishing\n construct libraries that meet Construct Hub requirements. For\n example, see{\" \"}\n <FAQLink href=\"https://dev.to/aws-builders/a-beginner-s-guide-to-create-aws-cdk-construct-library-with-projen-5eh4\">\n “A Beginner&apos;s Guide to Create AWS CDK ConstructLibrary with{\" \"}\n projen”\n </FAQLink>{\" \"}\n by <FAQLink href=\"https://hayao-k.dev/\">hayao-k</FAQLink>.\n </Text>\n\n <Text>\n If you already have a library written in TypeScript and want to\n migrate it to JSII so it can be included in Construct Hub, see the{\" \"}\n <FAQLink href=\"https://aws.github.io/jsii/user-guides/#library-author-guide\">\n JSII library author guide.\n </FAQLink>\n </Text>\n </FAQItem>\n\n <FAQItem question=\"What are the best practices for improving discoverability of a construct library on Construct Hub?\">\n <Text>\n To improve your construct library’s visibility on Construct Hub,\n follow these best practices:\n </Text>\n <OrderedList sx={{ li: { mt: 4 } }}>\n <ListItem>\n <strong>Helpful description.</strong> Publish your library with a\n description. Libraries without description have lower chances to\n be discovered by users. When you write your library’s description,\n think: Why would someone use it? What makes it unique? Make the\n description as accurate and differentiated as possible.\n </ListItem>\n\n <ListItem>\n <strong>Helpful keywords.</strong> Publish your library with\n helpful keywords, ones that can help potential users to find your\n package. Helpful keywords can be technologies that are being used\n by the library, use cases the library is useful for, service names\n that are being used by the library etc. For example: ‘Monitoring’,\n ‘Kubernetes’, ‘Cost Management’, ‘Websites’, ‘AI’, ‘Containers’\n and more.\n </ListItem>\n\n <ListItem>\n <strong>Helpful keywords.</strong> Publish your library with\n helpful keywords, ones that can help potential users to find your\n package. Helpful keywords can be technologies that are being used\n by the library, use cases the library is useful for, service names\n that are being used by the library etc. For example: ‘Monitoring’,\n ‘Kubernetes’, ‘Cost Management’, ‘Websites’, ‘AI’, ‘Containers’\n and more.\n </ListItem>\n\n <ListItem>\n <strong>Helpful README.</strong> Review your library’s README\n file. Is it developer-friendly? That is, can developers quickly\n understand the use case you’re trying to solve? Does your README\n make it easy to get started with your library? Does it explain how\n your library is different from other libraries? Is it easy to\n understand at first glance the value developers gain from the\n library? For more information see *“Q: What are the best practices\n for a developer-friendly README file?”.*\n </ListItem>\n\n <ListItem>\n <strong>API documentation.</strong> Document the library classes,\n methods, properties in the library’s code. Construct Hub will\n display this information when it automatically generates the API\n documentation.\n </ListItem>\n\n <ListItem>\n <strong>Maintain your library.</strong> Developers prefer\n libraries that are updated on a regular basis. Our experience\n shows that successful libraries are those where publishers engage\n and collaborate with the user community, respond to issues and\n pull requests, fix bugs, and add capabilities. To gain more\n developers trust, maintain the releases section on your code\n repository and make sure to describe the changes between different\n releases. You may consider to link the libraries you’ve published\n with your code repository.\n </ListItem>\n\n <ListItem>\n <strong>AWS Partner Network (APN) badge.</strong> If you’re an AWS\n partner and you are publishing a library for your offering, please\n reach out to us and we will be happy to add a badge to your\n libraries with your company’s name.\n </ListItem>\n\n <ListItem>\n <strong>\n Enable support for multiple programming languages.\n </strong>{\" \"}\n Make your library usable by a broader set of users and increase\n its value to the ecosystem. Starting with your library written in\n TypeScript, JSII will create packages in the other CDK programming\n languages. Construct Hub will then automatically generate API\n reference and transliterate code samples. All you need to do is to\n follow the instructions under *“Q: How can I add my construct to\n Construct Hub?”.*\n </ListItem>\n </OrderedList>\n </FAQItem>\n\n <FAQItem question=\"What are the best practices for writing a developer-friendly README file?\">\n <Text>\n Developer-friendly READMEs help readers quickly understand your\n library’s relevance to their needs and its unique value in\n comparison to similar libraries on the Construct Hub. Below is a\n suggestion for a README file structure:\n </Text>\n\n <UnorderedList sx={{ li: { mt: 4 } }}>\n <ListItem>\n <strong>State and maturity of the library.</strong> Start your\n READMEs with helpful badges like{\" \"}\n <FAQLink href=\"https://www.npmjs.com/package/cdk-codepipeline-badge-notification\">\n CDK pipelines badges\n </FAQLink>\n . It will help users see the state of your package.\n </ListItem>\n\n <ListItem>\n <strong>Short description</strong>. What does this library do?\n Which use case does it solve? Which technologies and services does\n it use or support?\n </ListItem>\n\n <ListItem>\n <strong>What is unique about this library?</strong> Help readers\n quickly find the right library for their needs by stating its\n special advantages right up front. How does it compare to other\n libraries addressing the same need or that use the same\n technologies and services? You don’t need an explicit “us vs.\n them” feature checklist; just make sure you communicate your\n library’s unique value.\n </ListItem>\n\n <ListItem>\n <strong>Code samples.</strong> Include as many complete and\n working code samples as you can to help developers quickly\n understand how they can use your library. Some developers start\n reading code samples before anything else. Write your code samples\n in TypeScript, and Construct Hub will transliterate them to the\n other programming languages your library supports. A good practice\n is to include a minimal code sample of how to use your library in\n the first page of your README.\n </ListItem>\n\n <ListItem>\n <strong>Author information.</strong> Share information about you,\n other packages you’ve published, and additional helpful links that\n can improve your credibility with readers.\n </ListItem>\n\n <ListItem>\n <strong>License and support.</strong> Include a “License” and\n “Contributing” sections that invite users to contribute via links\n to your source code repository and issue tracker. (Construct Hub\n provides “License” and “Provide Feedback” in your library’s\n package page, but it’s convenient to have them in the README too.)\n </ListItem>\n\n <ListItem>\n <strong>Diagrams.</strong> Diagrams always help readers quickly\n understand what a library does. Consider adding diagrams for\n libraries that create multiple services that work together.\n </ListItem>\n\n <ListItem>\n <strong>Explanatory videos.</strong> Consider sharing links to\n videos that can help potential customers engage with your library.\n </ListItem>\n\n <ListItem>\n <strong>Absolute links vs. relative.</strong> Use absolute links\n (those that start with http:// or https://) and not relative\n links. Relative links are prone to breaking when the content is\n shared elsewhere.\n </ListItem>\n </UnorderedList>\n </FAQItem>\n\n <FAQItem question=\"Why isn’t my package displayed on Construct Hub?\">\n <Text>\n Construct Hub includes publicly-available constructs that are\n JSII-compatible and that were published to the npm Registry with a\n permissive open-source license and a CDK keyword: aws-cdk, cdk8s, or\n cdktf. If you believe your package qualifies, but it still does not\n appear in Construct Hub, please raise an issue{\" \"}\n <FAQLink href={`${CONSTRUCT_HUB_REPO_URL}/issues/new`}>\n here\n </FAQLink>\n .\n </Text>\n </FAQItem>\n\n <FAQItem question=\"Can I update my package after it has been displayed?\">\n <Text>\n Yes, you can and should! After you publish a new valid version to\n the public npm Registry, it should appear on Construct Hub in about\n 30 minutes.\n </Text>\n </FAQItem>\n\n <FAQItem question=\"How can I report a bug or contribute code to a construct?\">\n <Text>\n Each package is owned by its publisher, so contributions, such as\n bug reports and pull requests, should be made via the repository\n link provided by the publisher. You may press the ‘Provide feedback’\n link at the package page to open a new issue in at the package’s\n repository.\n </Text>\n </FAQItem>\n\n <FAQItem question=\"How can I participate in link the Construct Hub community?\">\n Construct Hub is itself an open-source construct! Join the{\" \"}\n <FAQLink href=\"https://github.com/cdklabs/construct-hub\">\n Construct Hub GitHub community\n </FAQLink>\n . You are also welcome to join the #construct-hub-dev channel in the{\" \"}\n <FAQLink href=\"https://cdk.dev/\">\n CDK community Slack workspace\n </FAQLink>\n </FAQItem>\n\n <FAQItem question=\"Is there a Slack channel for the CDK community?\">\n <Text>\n Please join the{\" \"}\n <FAQLink href=\"https://cdk.dev/\">CDK Slack channel</FAQLink>. This\n Slack channel is managed by the CDK community, for the CDK\n community.\n </Text>\n </FAQItem>\n </Accordion>\n </FAQ>\n </Page>\n);\n"],"sourceRoot":""}
@@ -1,2 +0,0 @@
1
- (this["webpackJsonpconstruct-hub-webapp"]=this["webpackJsonpconstruct-hub-webapp"]||[]).push([[8],{208:function(e,t,n){"use strict";n.d(t,"a",(function(){return s}));var a=n(0),c=n(225),r={contribute:{event:{name:"Contribute Load"}},home:{event:{name:"Home Load"}},faq:{event:{name:"Frequently Asked Questions Load"}},packageProfile:{event:{name:"Package Profile Load"}},search:{event:{name:"Search Load"}},siteTerms:{event:{name:"Site Terms Load"}},notFound:{page:{pageType:"errorPage"},event:{name:"404 Page Load"}}},i=n(34),o=n(2),s=(["default-src 'self' 'unsafe-inline' http://*.awsstatic.com;","connect-src 'self' https://*.shortbread.aws.dev http://*.shortbread.aws.dev http://a0.awsstatic.com/ http://amazonwebservices.d2.sc.omtrdc.net http://aws.demdex.net http://dpm.demdex.net http://cm.everesttech.net;","frame-src http://aws.demdex.net http://dpm.demdex.net;","img-src 'self' https://* http://a0.awsstatic.com/ http://amazonwebservices.d2.sc.omtrdc.net http://aws.demdex.net http://dpm.demdex.net http://cm.everesttech.net;","object-src 'none';","style-src 'self' 'unsafe-inline';"].join(" "),function(e){var t=e.children,n=e.meta,s=e.pageName,l=Object(i.d)(r[s]);Object(a.useEffect)((function(){l()}),[l]);var d=n.suffix,u=void 0===d||d,j=n.title,b=n.description,f=u?"".concat(j," - Construct Hub"):j;return Object(o.jsxs)(o.Fragment,{children:[Object(o.jsxs)(c.a,{children:[!1,Object(o.jsx)("meta",{content:"width=device-width, initial-scale=1",name:"viewport"}),Object(o.jsx)("meta",{charSet:"utf-8"}),Object(o.jsx)("title",{children:f}),Object(o.jsx)("meta",{content:f,property:"og:title"}),Object(o.jsx)("meta",{content:f,name:"twitter:title"}),Object(o.jsx)("meta",{content:"summary",name:"twitter:card"}),Object(o.jsx)("meta",{content:b,name:"description"}),Object(o.jsx)("meta",{content:b,property:"og:description"}),Object(o.jsx)("meta",{content:b,name:"twitter:description"})]}),t]})})},218:function(e,t,n){"use strict";n.d(t,"a",(function(){return i})),n.d(t,"b",(function(){return o}));var a=n(6),c=n(32),r=n(110),i=function(e){return!e||e.length<1?[]:e.reduce((function(e,t){return t.highlight?[].concat(Object(c.a)(e),[t.highlight]):e}),[])},o=function(e){for(var t=e.packageTags,n=e.keywords,i=new Array,o=new Set,s=0,l=[].concat(Object(c.a)(function(e){return(null!==e&&void 0!==e?e:[]).filter((function(e){var t;return Boolean(null===(t=e.keyword)||void 0===t?void 0:t.label)})).map((function(e){var t;return Object(a.a)(Object(a.a)({},e),{},{id:null===(t=e.keyword)||void 0===t?void 0:t.label})}))}(t)),Object(c.a)(function(e){return!e||e.length<1?[]:e.filter((function(e){return Boolean(e)&&!r.a.has(e)})).map((function(e){return{id:e,keyword:{label:e}}}))}(n)));s<l.length;s++){var d=l[s],u=d.keyword.label.toLowerCase();o.has(u)||(i.push(d),o.add(u))}return i}},224:function(e,t,n){"use strict";n.d(t,"a",(function(){return r}));var a=n(0),c=n(22),r=function(){var e=Object(c.h)().search;return Object(a.useMemo)((function(){return new URLSearchParams(e)}),[e])}},231:function(e,t,n){"use strict";n.d(t,"a",(function(){return c}));var a=n(89),c=function(e){var t=Object(a.b)().data;return(null!==t&&void 0!==t?t:{})[e]}},232:function(e,t,n){"use strict";n.d(t,"a",(function(){return b}));var a=n(18),c=n(0),r=n(22),i=n(108),o=n(15),s=n(224),l=i.d.TypeScript,d="preferred-language",u=function(e){return null!=e&&i.e.has(e)},j=function(e){if(u(e))return e;try{var t,n=null!==(t=localStorage.getItem(d))&&void 0!==t?t:"";if(u(n))return n}catch(a){}return l},b=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.updateUrl,n=e.updateSaved,i=Object(r.h)(),l=i.pathname,b=i.hash,f=Object(r.g)(),O=f.replace,h=Object(s.a)(),m=h.get(o.b.LANGUAGE),g=Object(c.useState)((function(){return j(m)})),v=Object(a.a)(g,2),p=v[0],x=v[1];Object(c.useEffect)((function(){u(m)&&m!==p&&x(m)}),[m]),Object(c.useEffect)((function(){m!==p&&t&&(h.set(o.b.LANGUAGE,p),O({pathname:l,hash:b,search:h.toString()}))}),[p,t]);var y=Object(c.useCallback)((function(e){if(x(e),n)try{localStorage.setItem(d,e)}catch(t){}}),[n]);return Object(c.useMemo)((function(){return[p,y]}),[p,y])}},242:function(e,t,n){"use strict";var a;n.d(t,"b",(function(){return a})),n.d(t,"a",(function(){return K})),function(e){e.Wide="wide"}(a||(a={}));var c=n(6),r=n(0),i=n(124),o=n(127),s=n(593),l=n(88),d=n(83),u=n(43),j=n(243),b=n(58),f=Object(b.a)("packageCard",["author","description","downloads","languages","published","title","version","comment","wideContainer"]),O=n(2),h=function(e){var t=e["data-testid"],n=e.tooltip,a=e.value;return Object(O.jsx)(o.a,{hasArrow:!0,isDisabled:!n,label:n,placement:"left",children:Object(O.jsx)(i.q,{"data-testid":t,fontSize:"xs",zIndex:1,children:a})})},m=function(){var e,t,n,a=z(),c=a.author,r=a.metadata.date,i=a.name,o=Object(l.b)().data,b=null===o||void 0===o||null===(e=o.packages)||void 0===e||null===(t=e[i])||void 0===t||null===(n=t.downloads)||void 0===n?void 0:n.npm,m="string"===typeof c?c:c.name,g=new Date(r);return Object(O.jsxs)(O.Fragment,{children:[void 0!==b&&Object(O.jsx)(h,{"data-testid":f.downloads,tooltip:"Download numbers are periodically sourced from the npm registry",value:"".concat(b.toLocaleString()," weekly downloads")}),Object(O.jsx)(h,{"data-testid":f.published,value:Object(O.jsx)(j.a,{date:g,fontSize:"xs",formattedDate:Object(s.a)(g,{addSuffix:!0})})}),Object(O.jsx)(h,{"data-testid":f.author,value:Object(O.jsxs)(O.Fragment,{children:["By"," ",Object(O.jsx)(u.a,{color:"blue.500",to:Object(d.c)({query:m}),children:m})]})})]})},g=n(18),v=n(28),p=n(34),x=n(232),y=n(112),w=function(e){var t=e.comment;return Object(O.jsxs)(i.q,{"data-testid":f.comment,fontSize:"md",lineHeight:"tall",noOfLines:4,children:[Object(O.jsxs)(i.q,{as:"span",color:"blue.500",fontWeight:"bold",children:["Editor's note:"," "]}),t]})},k=function(){var e=Object(x.a)(),t=Object(g.a)(e,1)[0],n=z(),a=n.dataEvent,c=n.description,r=n.comment,o=n.metadata.constructFramework,s=n.name,l=n.version,u=null===o||void 0===o?void 0:o.name,j=null===o||void 0===o?void 0:o.majorVersion;return Object(O.jsxs)(O.Fragment,{children:[Object(O.jsx)(i.l,{as:v.b,"data-event":a?Object(p.b)(a,"Package Card",s):void 0,to:Object(d.a)({name:s,version:l,language:t}),children:Object(O.jsxs)(i.f,{align:"center",children:[Object(O.jsx)(y.a,{majorVersion:j,mr:2,name:u}),Object(O.jsx)(i.i,{as:"h3",color:"blue.800","data-testid":f.title,fontSize:"md",fontWeight:"bold",wordBreak:"normal",children:s})]})}),r?Object(O.jsx)(w,{comment:r}):Object(O.jsx)(i.q,{color:"blue.800","data-testid":f.description,fontSize:"md",lineHeight:"tall",noOfLines:4,children:c||"No description available."})]})},C=n(218),S=n(244),D=function(){var e,t,n=(null!==(e=null===(t=z())||void 0===t?void 0:t.metadata)&&void 0!==e?e:{}).packageTags,a=void 0===n?[]:n,r=Object(C.a)(a),o=Object(g.a)(r,1)[0];return o?Object(O.jsx)(i.b,{fontSize:"xs",children:Object(O.jsx)(S.a,Object(c.a)({},o))}):null},T=n(108),P=n(246),F={sm:5,md:6,lg:8},A=function(e){var t=e.isRounded,n=void 0!==t&&t,a=e.languages,c=e.name,r=e.size,i=void 0===r?"md":r,o=e.version,s=Object.keys(null!==a&&void 0!==a?a:{});return Object(O.jsx)(O.Fragment,{children:Object.entries(T.c).sort((function(e,t){var n=Object(g.a)(e,1)[0],a=Object(g.a)(t,1)[0];return T.a.indexOf(n)-T.a.indexOf(a)})).map((function(e){var t=Object(g.a)(e,2),a=t[0],r=t[1],l=a,u=l===T.d.TypeScript||s.includes(l),j=l===T.d.TypeScript||T.e.has(l);if(!u)return null;var b=r.name,f=r.icon,h=Object(O.jsx)(f,{"aria-label":"Supports ".concat(b),borderRadius:n?"50%":0,h:F[i],opacity:j?1:.2,w:F[i]});return Object(O.jsx)(P.a,{language:l,children:j?Object(O.jsx)(v.b,{"aria-label":"View package docs for ".concat(l),to:Object(d.a)({name:c,version:o,language:l}),children:h}):h},l)}))})},I=function(){var e=z();return Object(O.jsx)(A,Object(c.a)(Object(c.a)({},e),{},{size:"sm"}))},L=n(245),E=function(){var e=z(),t=e.keywords,n=void 0===t?[]:t,a=e.metadata.packageTags,c=void 0===a?[]:a,r=Object(C.b)({packageTags:c,keywords:n});return Object(O.jsx)(O.Fragment,{children:r.slice(0,10).map((function(e){var t=e.id,n=e.keyword,a=(n=void 0===n?{}:n).label,c=n.color;return Object(O.jsx)(L.a,{value:t,variant:c,children:a},t)}))})},q=function(){return Object(O.jsx)(i.k,{_hover:{"> article":{bg:"gray.50"}},children:Object(O.jsxs)(i.g,{as:"article",bg:"white",border:"base",borderRadius:"sm",boxShadow:"base",color:"blue.800","data-testid":f.wideContainer,h:"full",minH:"12.5rem",templateColumns:{base:"1fr",lg:"1fr 14rem"},w:"full",children:[Object(O.jsxs)(i.f,{direction:"column",justify:"space-between",p:5,sx:{gap:"0.5rem"},children:[Object(O.jsx)(i.p,{spacing:3,children:Object(O.jsx)(k,{})}),Object(O.jsx)(i.f,{align:"center",sx:{gap:"0.5rem"},wrap:"wrap",children:Object(O.jsx)(E,{})})]}),Object(O.jsxs)(i.f,{align:{base:"end",lg:"initial"},borderLeft:{lg:"base"},borderTop:{base:"base",lg:"none"},direction:{base:"row",lg:"column"},justify:"space-between",p:5,sx:{gap:"0.5rem"},children:[Object(O.jsxs)(i.p,{spacing:1,children:[Object(O.jsx)(D,{}),Object(O.jsx)(i.p,{spacing:1,children:Object(O.jsx)(m,{})})]}),Object(O.jsx)(i.p,{"data-testid":f.languages,direction:"row",spacing:2,children:Object(O.jsx)(I,{})})]})]})})},R=Object(r.createContext)(null),z=function(){return Object(r.useContext)(R)},K=function(e){var t=e["data-event"],n=e.pkg,r=e.variant,i=void 0===r?a.Wide:r;return Object(O.jsx)(R.Provider,{value:Object(c.a)(Object(c.a)({},n),{},{dataEvent:t}),children:i===a.Wide&&Object(O.jsx)(q,{})})}},243:function(e,t,n){"use strict";n.d(t,"a",(function(){return d}));var a=n(6),c=n(21),r=n(3),i=n(124),o=n(599),s=n(2),l=["date","format","formattedDate"],d=Object(r.e)((function(e,t){var n=e.date,r=e.format,d=e.formattedDate,u=Object(c.a)(e,l);return Object(s.jsx)(i.b,Object(a.a)(Object(a.a)({as:"time",dateTime:n.toISOString(),ref:t},u),{},{children:null!==d&&void 0!==d?d:Object(o.a)(n,null!==r&&void 0!==r?r:"")}))}));d.displayName="Time"},244:function(e,t,n){"use strict";n.d(t,"a",(function(){return i}));var a=n(124),c=n(130),r=n(2),i=function(e){var t=e.label,n=e.color,i=e.icon;return Object(r.jsxs)(a.p,{align:"center",direction:"row",spacing:2,children:[Object(r.jsx)(c.a,{alt:"".concat(t," icon"),src:i,w:4}),Object(r.jsx)(a.q,{color:n,fontWeight:"bold",children:t})]})}},245:function(e,t,n){"use strict";n.d(t,"a",(function(){return d}));var a=n(6),c=n(21),r=n(148),i=n(83),o=n(43),s=n(2),l=["children","value","label","zIndex"],d=function(e){var t=e.children,n=e.value,d=e.label,u=void 0===d?n:d,j=e.zIndex,b=Object(c.a)(e,l);return Object(s.jsx)(o.a,{"aria-label":"Tag: ".concat(u),to:Object(i.c)({keywords:[n]}),zIndex:j,children:Object(s.jsx)(r.a,Object(a.a)(Object(a.a)({_hover:{textDecoration:"underline"}},b),{},{children:Object(s.jsx)(r.b,{children:t})}))})}},246:function(e,t,n){"use strict";n.d(t,"a",(function(){return i}));var a=n(127),c=n(108),r=n(2),i=function(e){var t=e.children,n=e.language,i=c.e.has(n),o=c.b[n],s=i?"Click to view documentation in ".concat(o):"Documentation support for ".concat(o," is coming soon!");return Object(r.jsx)(a.a,{hasArrow:!0,label:s,placement:"top-start",children:Object(r.jsx)("span",{children:t})})}},598:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return me}));var a,c=n(124),r=n(208),i=n(137),o=n(32),s=n(10),l=n(6),d=n(18),u=n(0),j=n(42),b=n(86),f=n(152),O=n(31),h=n(147),m=n(151),g=n(2),v=function(e){var t=e.name,n=e.hint,a=Object(h.a)({base:"auto",md:"right"});return Object(g.jsxs)(c.f,{align:"center",mb:1,children:[Object(g.jsx)(c.i,{as:"h4",size:"sm",w:"max-content",children:t}),n?Object(g.jsxs)(m.a,{colorScheme:"dark",placement:a,strategy:"fixed",children:[Object(g.jsx)(m.e,{children:Object(g.jsx)(c.f,{"aria-label":"Hint: ".concat(t),as:"button",ml:2,children:Object(g.jsx)(O.l,{h:3.5,w:3.5})})}),Object(g.jsxs)(m.d,{bg:"gray.700",borderRadius:"base",color:"white",fontSize:"sm",mx:{base:"1rem",md:"initial"},shadow:"whiteAlpha.300",children:[Object(g.jsx)(m.b,{bg:"gray.700"}),Object(g.jsx)(m.c,{children:Object(g.jsx)(c.q,{children:n})})]})]}):null]})},p=n(58),x=Object(p.a)("searchRedesign",["page","searchDetails","nextPage","prevPage","goToPage","sortButton","sortDropdown","sortItem","filtersPanel","cdkTypeFilter","cdkVersionFilter","filterItem","languagesFilter"]),y=function(e){var t=e["data-testid"],n=e.value,a=e.onValueChange,r=e.options,i=e.name,o=e.hint;return Object(g.jsxs)(c.p,{"data-testid":t,spacing:1,children:[Object(g.jsx)(v,{hint:o,name:i}),Object(g.jsx)(f.b,{onChange:a,value:n,children:Object(g.jsx)(c.p,{spacing:1,children:r.map((function(e){var t=e.display,n=e.value;return Object(g.jsx)(f.a,{value:n,children:Object(g.jsx)(c.q,{color:"gray.600","data-testid":x.filterItem,"data-value":n,isTruncated:!0,children:t})},n)}))})})]})},w=n(15),k=n(96),C=n(224),S=n(51),D=(a={},Object(s.a)(a,S.a.NameAsc,"A-Z"),Object(s.a)(a,S.a.NameDesc,"Z-A"),Object(s.a)(a,S.a.PublishDateAsc,"Oldest first"),Object(s.a)(a,S.a.PublishDateDesc,"Newest first"),Object(s.a)(a,S.a.DownloadsDesc,"Most downloads"),Object(s.a)(a,S.a.DownloadsAsc,"Least downloads"),a),T=function(e){var t=parseInt(e);return"NaN"==="".concat(t)?0:t},P=function(e){return e?decodeURIComponent(e).split(","):[]},F=Object(u.createContext)(void 0),A=function(){var e=Object(u.useContext)(F);if(!e)throw new Error("This hook must be called in a child of <SearchStateProvider />");return e},I=function(e){var t,n,a,c,r=e.children,i=Object(C.a)(),o=T(null!==(t=i.get(w.b.OFFSET))&&void 0!==t?t:"0"),s=decodeURIComponent(null!==(n=i.get(w.b.SEARCH_QUERY))&&void 0!==n?n:""),l=P(i.get(w.b.LANGUAGES)),d=i.get(w.b.TAGS),j=Object(u.useMemo)((function(){return P(d)}),[d]),b=i.get(w.b.KEYWORDS),f=Object(u.useMemo)((function(){return P(b)}),[b]),O=null!==(a=i.get(w.b.SORT))&&void 0!==a?a:void 0,h=null!==(c=i.get(w.b.CDK_TYPE))&&void 0!==c?c:void 0,m=i.get(w.b.CDK_MAJOR),v=m?T(m):void 0,p=Object(k.a)({defaultCdkMajor:v,defaultCdkType:h,defaultKeywords:f,defaultLanguages:l,defaultQuery:s,defaultSort:O,defaultTags:j});return Object(u.useEffect)((function(){s!==p.query&&p.setQuery(s)}),[s]),Object(u.useEffect)((function(){f.some((function(e){return!p.keywords.includes(e)}))&&p.setKeywords(f)}),[f]),Object(u.useEffect)((function(){j.some((function(e){return!p.tags.includes(e)}))&&p.setTags(j)}),[j]),Object(g.jsx)(F.Provider,{value:{limit:25,offset:o,query:s,searchAPI:p},children:r})},L=function(){var e,t=A().searchAPI,n=t.cdkType,a=t.setCdkType,c=t.cdkMajor,r=t.setCdkMajor,i=Object(b.b)(),f=Object(u.useMemo)((function(){var e=i.constructFrameworks,t=Object.entries(e).reduce((function(e,t){var n=Object(d.a)(t,2),a=n[0],c=n[1];return c.pkgCount<1?e:Object(l.a)(Object(l.a)({},e),{},Object(s.a)({},a,Object(l.a)({display:j.a[a],value:a},c)))}),{});return Object.keys(t).length?t:void 0}),[i]),O=Object(u.useMemo)((function(){var e;if(f&&n){var t=null===(e=f[n])||void 0===e?void 0:e.majorVersions;if(t)return Object(o.a)(t).sort((function(e,t){return e-t})).map((function(e){return{value:e.toString(),display:"".concat(j.a[n]," v").concat(e)}}))}}),[f,n]);if(!f)return null;return Object(g.jsxs)(g.Fragment,{children:[Object(g.jsx)(y,{"data-testid":x.cdkTypeFilter,hint:"Choose the right CDK for your IaC technology: AWS CDK for AWS CloudFormation, CDKtf for Terraform, or CDK8s for Kubernetes.",name:"CDK Type",onValueChange:function(e){var t=e;r(void 0),a(e?t:void 0)},options:[{display:"Any CDK Type",value:""}].concat(Object(o.a)(Object.values(f))),value:null!==n&&void 0!==n?n:""}),!!(O&&O.length>1)&&Object(g.jsx)(y,{"data-testid":x.cdkVersionFilter,hint:"Choose the major version of the CDK you're using to see only constructs that will work with that version.",name:"CDK Major Version",onValueChange:function(e){if(e){var t=parseInt(e,10);r(t)}else r(void 0)},options:[{display:"Any Major Version",value:""}].concat(Object(o.a)(O)),value:null!==(e=null===c||void 0===c?void 0:c.toString())&&void 0!==e?e:""})]})},E=n(125),q=n(127),R=n(11),z=n(48),K=n(126),W=function(e){var t=e.display,n=e.value,a=e.isDisabled,r=e.disabledHint,i=e.isChecked,o=e.onChange;return Object(g.jsx)(E.a,{isChecked:i,isDisabled:a,onChange:o,children:Object(g.jsx)(q.a,{hasArrow:!0,isDisabled:!a&&!r,label:r,placement:"right",children:Object(g.jsx)(c.q,{color:"gray.600","data-testid":x.filterItem,"data-value":n,isTruncated:!0,children:t})})},n)},M=function(e){var t=e["data-testid"],n=e.initialItemCount,a=e.hint,r=e.name,i=e.options,o=e.values,s=e.onValueChange,d=Object(R.g)(),j=function(e){return function(){s(e)}},b=i,f=[];n&&(b=i.slice(0,n),f=i.slice(n,i.length));var h=f.length>0;return Object(g.jsxs)(c.f,{"data-testid":t,direction:"column",children:[Object(g.jsx)(v,{hint:a,name:r}),Object(g.jsxs)(c.p,{mt:1,spacing:1,children:[b.map((function(e){return Object(u.createElement)(W,Object(l.a)(Object(l.a)({},e),{},{isChecked:o.includes(e.value),key:e.value,onChange:j(e.value)}))})),h&&Object(g.jsx)(z.a,{animateOpacity:!0,in:d.isOpen,unmountOnExit:!0,children:Object(g.jsx)(c.p,{spacing:1,children:f.map((function(e){return Object(u.createElement)(W,Object(l.a)(Object(l.a)({},e),{},{isChecked:o.includes(e.value),key:e.value,onChange:j(e.value)}))}))})})]}),h&&Object(g.jsx)(c.f,{align:"start",mt:1,children:Object(g.jsx)(K.a,{color:"gray.600",fontWeight:"normal",leftIcon:d.isOpen?Object(g.jsx)(O.f,{}):Object(g.jsx)(O.c,{}),onClick:d.onToggle,size:"sm",textAlign:"left",variant:"link",w:"auto",children:d.isOpen?"Show fewer options (".concat(b.length,")"):"Show more options (".concat(f.length,")")})})]})},V=function(){var e=A().searchAPI,t=e.keywords,n=e.setKeywords,a=Object(b.b)().keywords,c=Object(u.useMemo)((function(){var e=Object(o.a)(a.entries()).sort((function(e,t){return Object(d.a)(e,2)[1]<Object(d.a)(t,2)[1]?1:-1})).filter((function(e){var n=Object(d.a)(e,1)[0];return!t.includes(n)})).map((function(e){var t=Object(d.a)(e,1)[0];return{display:t,value:t}})).slice(0,25),n=t.filter((function(t){return!e.some((function(e){return e.value===t}))}));return[].concat(Object(o.a)(n.map((function(e){return{display:e,value:e}}))),Object(o.a)(e))}),[a,t]);return Object(g.jsx)(M,{"data-testid":x.languagesFilter,hint:"Focus the results by choosing one or more keywords reflecting the kind of construct you're looking for. Keywords are provided by construct authors.",initialItemCount:5,name:"Keywords",onValueChange:function(e){n(t.includes(e)?t.filter((function(t){return t!==e})):[].concat(Object(o.a)(t),[e]))},options:c,values:t})},N=n(108),U=Object.entries(N.b).map((function(e){var t=Object(d.a)(e,2),n=t[0],a=t[1];return Object(l.a)({display:a,value:n},N.e.has(n)?{isDisabled:!1}:{isDisabled:!0,disabledHint:"".concat(N.b[n]," support is coming soon!")})})).sort((function(e,t){return e.isDisabled>t.isDisabled?1:-1})),H=function(){var e=A().searchAPI,t=e.languages,n=e.setLanguages;return Object(g.jsx)(M,{"data-testid":x.languagesFilter,hint:"Choose one or more languages. Results include constructs for use with at least one of the selected languages.",name:"Programming Language",onValueChange:function(e){var a=e;n(t.includes(a)?t.filter((function(e){return e!==a})):[].concat(Object(o.a)(t),[a]))},options:U,values:t})},B=n(231),G=function(){var e,t,n=(null!==(e=null===(t=Object(B.a)("packageTags"))||void 0===t?void 0:t.filter((function(e){return Boolean(e.searchFilter)})))&&void 0!==e?e:[]).reduce((function(e,t){var n,a,c=null===(n=t.searchFilter)||void 0===n?void 0:n.groupBy;return c?Object(l.a)(Object(l.a)({},e),{},Object(s.a)({},c,[].concat(Object(o.a)(null!==(a=e[c])&&void 0!==a?a:[]),[t]))):e}),{}),a=A().searchAPI,c=a.tags,r=a.setTags,i=function(e){r(c.includes(e)?c.filter((function(t){return t!==e})):[].concat(Object(o.a)(c),[e]))};return Object(g.jsx)(g.Fragment,{children:Object.entries(n).map((function(e){var t=Object(d.a)(e,2),n=t[0],a=t[1];return Object(g.jsx)(M,{name:n,onValueChange:i,options:a.map((function(e){return{display:e.searchFilter.display,value:e.id}})),values:c},n)}))})},Q="5.75rem",_=function(){return Object(g.jsx)(i.a,{borderRadius:"none",boxShadow:"none","data-testid":x.filtersPanel,display:{base:"none",md:"flex"},maxH:"calc(100vh - ".concat(Q," - 1.25rem)"),maxW:"23rem",minW:"100%",overflow:"hidden auto",p:4,pos:"sticky",top:Q,zIndex:"docked",children:Object(g.jsxs)(c.p,{color:"blue.800",h:"max-content",spacing:4,top:4,children:[Object(g.jsx)(c.i,{as:"h3",size:"sm",children:"Filters"}),Object(g.jsx)(L,{}),Object(g.jsx)(H,{}),Object(g.jsx)(G,{}),Object(g.jsx)(V,{})]})})},J=n(22),Y=n(93),Z=n(242),X=Object(s.a)({},Z.b.Wide,(function(e){var t=e.items;return Object(g.jsx)(c.p,{spacing:4,children:t.map((function(e){return Object(g.jsx)(Z.a,{pkg:e,variant:Z.b.Wide},"".concat(e.name,"-").concat(e.version))}))})})),$=Object(u.memo)((function(e){var t=e.cardView,n=void 0===t?Z.b.Wide:t,a=e.items;if(e.loading||!a)return Object(g.jsx)(c.c,{children:Object(g.jsx)(Y.a,{size:"xl"})});var r=X[n];return Object(g.jsx)(r,{items:a})}));$.displayName="PackageList";var ee=n(68),te=n(111),ne=n(83),ae=n(28),ce=function(e){var t=e["data-testid"],n=e.icon,a=e.offset,c=e.getPageUrl,r={"aria-label":"Page ".concat(a," link"),borderRadius:"md",borderColor:"blue.500",colorScheme:"blue","data-testid":t,icon:Object(g.jsx)(n,{color:"blue.500",h:5,w:5}),mx:2,h:10,w:10,variant:"outline"};return void 0!==a?Object(g.jsx)(K.b,Object(l.a)(Object(l.a)({},r),{},{as:ae.b,to:c({offset:a})})):Object(g.jsx)(K.b,Object(l.a)(Object(l.a)({},r),{},{disabled:!0}))},re=n(129),ie=function(e){var t=e["data-testid"],n=e.pageLimit,a=e.offset,r=e.getPageUrl,i=Object(u.useState)((a+1).toString()),o=Object(d.a)(i,2),s=o[0],l=o[1],j=Object(J.g)().push;Object(u.useEffect)((function(){l((a+1).toString())}),[a]);return Object(g.jsxs)(c.f,{align:"center",as:"form",mx:2,onSubmit:function(e){e.preventDefault(),j(r({offset:parseInt(s)-1}))},children:[Object(g.jsx)(re.a,{colorScheme:"blue","data-testid":t,h:10,max:n+1,min:1,name:"page",onChange:function(e){e.preventDefault(),l(e.target.value)},p:0,textAlign:"center",type:"number",value:s,w:10}),Object(g.jsxs)(c.q,{ml:2,w:"max-content",children:["of ",n+1]})]})},oe=function(e){var t=e.offset,n=e.getPageUrl,a=e.pageLimit,r=t<a?t+1:void 0,i=t>0?t-1:void 0;return Object(g.jsxs)(c.p,{align:"center",direction:"row",justify:"space-between",maxW:"18rem",mx:"auto",spacing:4,w:"full",children:[Object(g.jsx)(ce,{"data-testid":x.prevPage,getPageUrl:n,icon:O.d,offset:i}),Object(g.jsx)(ie,{"data-testid":x.goToPage,getPageUrl:n,offset:t,pageLimit:a}),Object(g.jsx)(ce,{"data-testid":x.nextPage,getPageUrl:n,icon:O.e,offset:r})]})},se=function(e){var t=e.children;return Object(g.jsx)(c.q,{as:"strong",color:"gray.700",children:t})},le=function(e){var t=e.first,n=e.count,a=e.last;return!t&&a>=n?Object(g.jsxs)(g.Fragment,{children:[Object(g.jsx)(se,{children:n})," of ",Object(g.jsx)(se,{children:n})]}):Object(g.jsxs)(g.Fragment,{children:[Object(g.jsxs)(se,{children:[n?t+1:n," - ",a>n?n:a]})," ","of ",Object(g.jsx)(se,{children:n})]})},de=function(e){var t=e.limit,n=e.offset,a=e.count,r=e.filtered,i=e.query,o=t*n,s=o+t,l=a>0;return Object(g.jsxs)(c.q,{"data-testid":x.searchDetails,children:[l?Object(g.jsxs)(g.Fragment,{children:["Displaying ",Object(g.jsx)(le,{count:a,first:o,last:s})," ",r?"search results":"constructs"]}):Object(g.jsx)(g.Fragment,{children:r?"There were no search results":"No constructs found"}),i&&Object(g.jsxs)(g.Fragment,{children:[" for ",Object(g.jsx)(se,{children:i})]}),".",!l&&r&&Object(g.jsx)(g.Fragment,{children:" Try a different term."})]})},ue=n(133),je=function(){var e=A().searchAPI,t=e.sort,n=e.setSort;return Object(g.jsx)(y,{hint:"Sets the order of search results",name:"Sorted By",onValueChange:function(e){n(e||void 0)},options:[{display:"Relevance",value:""}].concat(Object(o.a)(Object.entries(D).map((function(e){var t=Object(d.a)(e,2),n=t[0];return{display:t[1],value:n}})))),value:null!==t&&void 0!==t?t:""})},be=function(){var e=Object(R.g)();return Object(g.jsxs)(g.Fragment,{children:[Object(g.jsx)(K.a,{colorScheme:"blue",display:{md:"none"},onClick:e.onOpen,rightIcon:Object(g.jsx)(O.c,{}),variant:"link",children:"Sorting and Filters"}),Object(g.jsxs)(ue.a,Object(l.a)(Object(l.a)({},e),{},{placement:"bottom",children:[Object(g.jsx)(ue.f,{}),Object(g.jsxs)(ue.d,{color:"blue.800",maxH:"full",children:[Object(g.jsx)(ue.e,{borderBottom:"base",children:"Sorting and Filters"}),Object(g.jsx)(ue.c,{}),Object(g.jsx)(ue.b,{children:Object(g.jsxs)(c.p,{color:"blue.800",pb:4,spacing:4,children:[Object(g.jsx)(je,{}),Object(g.jsx)(L,{}),Object(g.jsx)(H,{}),Object(g.jsx)(G,{}),Object(g.jsx)(V,{})]})})]})]}))]})},fe=n(128),Oe=function(){var e=A().searchAPI,t=e.sort,n=e.setSort,a=t?D[t]:"Relevance";return Object(g.jsxs)(c.f,{align:"center",children:[Object(g.jsx)(c.q,{children:"Sorted by"}),Object(g.jsxs)(fe.a,{children:[Object(g.jsx)(fe.b,{as:K.a,color:"blue.500","data-testid":x.sortButton,ml:2,pl:2,pr:2,py:1,rightIcon:Object(g.jsx)(O.c,{}),variant:"link",children:a}),Object(g.jsxs)(fe.f,{"data-testid":x.sortDropdown,minW:"180",zIndex:"sticky",children:[Object(g.jsx)(fe.e,{"data-testid":x.sortItem,"data-value":"",onClick:function(){return n(void 0)},children:"Relevance"},"Relevance"),Object.entries(D).map((function(e){var t=Object(d.a)(e,2),a=t[0],c=t[1];return Object(g.jsx)(fe.e,{"data-testid":x.sortItem,"data-value":a,onClick:function(){return n(a)},children:c},a)}))]})]})]})},he=function(){var e=Object(u.useRef)(!0),t=Object(J.g)().push,n=A(),a=n.query,i=n.searchAPI,o=n.offset,s=n.limit,l=i.keywords,d=i.languages,j=i.sort,b=i.cdkType,f=i.cdkMajor,O=i.onSearch,h=i.tags,m=Object(te.a)({offset:o,limit:s,query:a,keywords:l,languages:d,cdkMajor:f,cdkType:b,sort:j,tags:h}),v=m.page,p=m.pageLimit,x=m.results,y=function(e){var t,n;return Object(ne.c)({cdkMajor:f,cdkType:b,keywords:l,query:null!==(t=e.q)&&void 0!==t?t:a,languages:d,sort:j,offset:null!==(n=e.offset)&&void 0!==n?n:o,tags:h})};return Object(u.useEffect)((function(){x.length&&(o<0||o>p)&&t(y(o<0?{offset:0}:{offset:p}))}),[x,o,p]),Object(u.useEffect)((function(){e.current?e.current=!1:O({replace:!0})}),[j,l,d,b,f,h]),Object(u.useEffect)((function(){window.scrollTo(0,0)}),[v]),Object(g.jsx)(r.a,{meta:{title:a||"Search",description:a?"".concat(x.length," results for ").concat(a," at Construct Hub"):"Search reusable components for your cloud application"},pageName:"search",children:Object(g.jsxs)(c.p,{direction:"column",maxW:"100vw",pb:4,px:4,spacing:4,children:[Object(g.jsx)(ee.a,{bg:"white",onChange:i.onQueryChange,onSubmit:function(e){i.setSort(void 0),i.onSubmit(e)},value:i.query}),Object(g.jsxs)(c.p,{align:{base:"start",lg:"center"},direction:{base:"column-reverse",lg:"row"},justify:{base:"initial",lg:"space-between"},spacing:4,children:[Object(g.jsx)(de,{count:x.length,filtered:!!a,limit:s,offset:o,query:a}),Object(g.jsx)(c.b,{display:{base:"none",md:"initial"},children:Object(g.jsx)(Oe,{})}),Object(g.jsx)(c.b,{display:{md:"none"},children:Object(g.jsx)(be,{})})]}),Object(g.jsx)($,{items:v}),Object(g.jsx)(c.b,{w:"full",children:Object(g.jsx)(oe,{getPageUrl:y,offset:o,pageLimit:p})})]})})},me=function(){return Object(g.jsx)(I,{children:Object(g.jsx)(r.a,{meta:{title:"Search - Construct Hub",description:"Search Construct Libraries for AWS CDK, CDK8s, and CDKtf"},pageName:"search",children:Object(g.jsxs)(c.g,{"data-testid":x.page,gap:4,h:"full",maxW:"100%",px:{base:0,md:6},py:6,templateColumns:{base:"1fr",md:"auto 1fr"},templateRows:"1fr",children:[Object(g.jsx)(_,{}),Object(g.jsx)(he,{})]})})})}}}]);
2
- //# sourceMappingURL=8.ddcecc46.chunk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["constants/pageInfo.ts","components/Page/Page.tsx","util/package.ts","hooks/useQueryParams/useQueryParams.ts","hooks/useConfigValue/useConfigValue.ts","hooks/useLanguage/useLanguage.ts","components/PackageCard/constants.ts","components/PackageCard/testIds.ts","components/PackageCard/Details.tsx","components/PackageCard/EditorsNote.tsx","components/PackageCard/Heading.tsx","components/PackageCard/Highlight.tsx","components/PackageLanguages/PackageLanguages.tsx","components/PackageCard/Languages.tsx","components/PackageCard/Tags.tsx","components/PackageCard/WideCard.tsx","components/PackageCard/PackageCard.tsx","components/Time/Time.tsx","components/Highlight/Highlight.tsx","components/PackageTag/PackageTag.tsx","components/LanguageSupportTooltip/LanguageSupportTooltip.tsx","views/SearchRedesign/FilterHeading.tsx","views/SearchRedesign/testIds.ts","views/SearchRedesign/RadioFilter.tsx","views/SearchRedesign/constants.ts","views/SearchRedesign/util.ts","views/SearchRedesign/SearchState.tsx","views/SearchRedesign/CDKFilter.tsx","views/SearchRedesign/CheckboxFilter.tsx","views/SearchRedesign/KeywordsFilter.tsx","views/SearchRedesign/LanguageFilter.tsx","views/SearchRedesign/TagFilter.tsx","views/SearchRedesign/FilterPanel.tsx","components/PackageList/PackageList.tsx","components/PackageList/WideCardList.tsx","views/SearchRedesign/ArrowButton.tsx","views/SearchRedesign/GoToPage.tsx","views/SearchRedesign/PageControls.tsx","views/SearchRedesign/SearchDetails.tsx","views/SearchRedesign/SortFilter.tsx","views/SearchRedesign/SortAndFilterDrawer.tsx","views/SearchRedesign/SortedBy.tsx","views/SearchRedesign/SearchResults.tsx","views/SearchRedesign/SearchRedesign.tsx"],"names":["pageInfo","contribute","event","name","home","faq","packageProfile","search","siteTerms","notFound","page","pageType","Page","join","children","meta","pageName","trackPageView","usePageView","useEffect","suffix","title","description","formattedTitle","Helmet","process","content","charSet","property","highlightsFrom","packageTags","length","reduce","accum","tag","highlight","tagObjectsFrom","keywords","tagObjects","Array","tagLabels","Set","filter","Boolean","keyword","label","map","id","mapPackageTags","KEYWORD_IGNORE_LIST","has","mapPackageKeywords","toLowerCase","push","add","useQueryParams","useLocation","useMemo","URLSearchParams","useConfigValue","key","data","useConfig","defaultLang","Language","TypeScript","LOCAL_KEY","isValidLang","lang","TEMP_SUPPORTED_LANGUAGES","getInitialLang","langFromParams","storedLang","localStorage","getItem","useLanguage","options","updateUrl","updateSaved","pathname","hash","useHistory","replace","params","get","QUERY_PARAMS","LANGUAGE","useState","language","setLanguage","set","toString","update","useCallback","val","setItem","PackageCardType","testIds","createTestIds","Detail","dataTestid","tooltip","value","hasArrow","isDisabled","placement","fontSize","zIndex","Details","usePackageCard","author","date","metadata","useStats","downloads","packages","npm","authorName","publishDate","Date","undefined","toLocaleString","published","Time","formattedDate","formatDistanceToNowStrict","addSuffix","NavLink","color","to","getSearchPath","query","EditorsNote","comment","lineHeight","noOfLines","as","fontWeight","Heading","currentLanguage","dataEvent","constructFramework","version","cdkType","cdkVersion","majorVersion","Link","eventName","getPackagePath","align","CDKType","mr","wordBreak","Highlight","sizes","sm","md","lg","PackageLanguages","isRounded","languages","packageName","size","targets","Object","keys","entries","LANGUAGE_RENDER_MAP","sort","left","right","LANGUAGES","indexOf","info","isSupportedByLibrary","includes","isSupportedByConstructHub","Icon","icon","borderRadius","h","opacity","w","LanguageSupportTooltip","Languages","pkg","Tags","tags","slice","PackageTag","variant","WideCard","_hover","bg","border","boxShadow","wideContainer","minH","templateColumns","base","direction","justify","p","sx","gap","spacing","wrap","borderLeft","borderTop","PackageCardContext","createContext","useContext","PackageCard","Wide","Provider","forwardRef","ref","formatString","format","boxProps","dateTime","toISOString","displayName","alt","src","tagProps","textDecoration","isSupported","langName","LANGUAGE_NAME_MAP","message","FilterHeading","hint","useBreakpointValue","mb","colorScheme","strategy","ml","mx","shadow","RadioFilter","checkedValue","onValueChange","onChange","display","filterItem","isTruncated","SORT_RENDER_MAP","CatalogSearchSort","NameAsc","NameDesc","PublishDateAsc","PublishDateDesc","DownloadsDesc","DownloadsAsc","toNum","result","parseInt","parseQueryArray","queryString","decodeURIComponent","split","SearchStateContext","useSearchState","state","Error","SearchStateProvider","queryParams","offset","OFFSET","SEARCH_QUERY","tagQuery","TAGS","keywordQuery","KEYWORDS","SORT","CDK_TYPE","cdkMajorParam","CDK_MAJOR","cdkMajor","searchAPI","useCatalogSearch","defaultCdkMajor","defaultCdkType","defaultKeywords","defaultLanguages","defaultQuery","defaultSort","defaultTags","setQuery","some","k","setKeywords","t","setTags","limit","CDKFilter","setCdkType","setCdkMajor","useSearchContext","cdkOptions","cdkTypes","constructFrameworks","opts","pkgCount","CDKTYPE_NAME_MAP","majorsOptions","majorVersions","a","b","cdkTypeFilter","type","cdk","values","cdkVersionFilter","major","majorNum","CheckboxItem","disabledHint","isChecked","CheckboxFilter","initialItemCount","checkedValues","collapse","useDisclosure","getOnChange","alwaysShow","showWhenExpanded","isExpandible","mt","item","animateOpacity","in","isOpen","unmountOnExit","leftIcon","onClick","onToggle","textAlign","KeywordsFilter","keywordMap","keywordOptions","baseOptions","keywordsNotInOptions","opt","languagesFilter","languageOptions","l1","l2","LanguageFilter","setLanguages","l","TagFilter","tagFilterGroups","searchFilter","groupName","groupBy","onTagsChange","tagItems","TOP_OFFSET","FilterPanel","Card","filtersPanel","maxH","maxW","minW","overflow","pos","top","listViews","items","PackageList","memo","cardView","loading","View","ArrowButton","getPageUrl","props","borderColor","disabled","GoToPage","pageLimit","inputValue","setInputValue","onSubmit","e","preventDefault","max","min","target","PageControls","nextOffset","prevOffset","prevPage","ChevronLeftIcon","goToPage","nextPage","ChevronRightIcon","Em","Count","first","count","last","SearchDetails","filtered","hasResults","searchDetails","SortFilter","setSort","newSort","SortAndFilterDrawer","drawer","onOpen","rightIcon","borderBottom","pb","SortedBy","selected","Button","sortButton","pl","pr","py","sortDropdown","sortItem","SearchResults","isFirstRender","useRef","onSearch","useCatalogResults","results","getUrl","q","current","window","scrollTo","px","SearchBar","onQueryChange","SearchRedesign","templateRows"],"mappings":"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","file":"static/js/8.ddcecc46.chunk.js","sourcesContent":["export const pageInfo = {\n contribute: {\n event: {\n name: \"Contribute Load\",\n },\n },\n home: {\n event: {\n name: \"Home Load\",\n },\n },\n faq: {\n event: {\n name: \"Frequently Asked Questions Load\",\n },\n },\n packageProfile: {\n event: {\n name: \"Package Profile Load\",\n },\n },\n search: {\n event: {\n name: \"Search Load\",\n },\n },\n siteTerms: {\n event: {\n name: \"Site Terms Load\",\n },\n },\n notFound: {\n page: {\n pageType: \"errorPage\",\n },\n event: {\n name: \"404 Page Load\",\n },\n },\n} as const;\n","import { FunctionComponent, useEffect } from \"react\";\nimport { Helmet } from \"react-helmet\";\nimport { pageInfo } from \"../../constants/pageInfo\";\nimport { usePageView } from \"../../contexts/Analytics\";\n\nexport interface PageProps {\n pageName: keyof typeof pageInfo;\n meta: {\n suffix?: boolean;\n title: string;\n description: string;\n };\n}\n\n// Should be the same as the \"real\" CSP, except most things come from HTTP\n// instead of HTTPS (because it is protocol-relative, and the dev site is\n// served over plain HTTP).\nconst csp = [\n \"default-src 'self' 'unsafe-inline' http://*.awsstatic.com;\",\n \"connect-src 'self' https://*.shortbread.aws.dev http://*.shortbread.aws.dev http://a0.awsstatic.com/ http://amazonwebservices.d2.sc.omtrdc.net http://aws.demdex.net http://dpm.demdex.net http://cm.everesttech.net;\",\n \"frame-src http://aws.demdex.net http://dpm.demdex.net;\",\n \"img-src 'self' https://* http://a0.awsstatic.com/ http://amazonwebservices.d2.sc.omtrdc.net http://aws.demdex.net http://dpm.demdex.net http://cm.everesttech.net;\",\n \"object-src 'none';\",\n \"style-src 'self' 'unsafe-inline';\",\n].join(\" \");\n\nexport const Page: FunctionComponent<PageProps> = ({\n children,\n meta,\n pageName,\n}) => {\n const trackPageView = usePageView(pageInfo[pageName]);\n\n useEffect(() => {\n trackPageView();\n }, [trackPageView]);\n\n const { suffix = true, title, description } = meta;\n const formattedTitle = suffix ? `${title} - Construct Hub` : title;\n\n return (\n <>\n <Helmet>\n {process.env.NODE_ENV === \"development\" && (\n <meta content={csp} httpEquiv=\"Content-Security-Policy\" />\n )}\n\n <meta content=\"width=device-width, initial-scale=1\" name=\"viewport\" />\n <meta charSet=\"utf-8\" />\n\n <title>{formattedTitle}</title>\n <meta content={formattedTitle} property=\"og:title\" />\n <meta content={formattedTitle} name=\"twitter:title\" />\n <meta content=\"summary\" name=\"twitter:card\" />\n\n <meta content={description} name=\"description\" />\n <meta content={description} property=\"og:description\" />\n <meta content={description} name=\"twitter:description\" />\n </Helmet>\n {children}\n </>\n );\n};\n","import { PackageHighlight, PackageTagConfig } from \"../api/config\";\nimport { KEYWORD_IGNORE_LIST } from \"../constants/keywords\";\n\nexport interface TagObject extends PackageTagConfig {}\n\n/**\n * Reduces package tags to only return highlight tags\n */\nexport const highlightsFrom = (packageTags?: PackageTagConfig[]) => {\n if (!packageTags || packageTags.length < 1) return [];\n\n return packageTags.reduce(\n (accum: PackageHighlight[], tag: PackageTagConfig): PackageHighlight[] => {\n if (tag.highlight) {\n return [...accum, tag.highlight];\n }\n\n return accum;\n },\n []\n );\n};\n\n/**\n * Maps packageTags to an array of TagObjects, which can be rendered by the PackageTags Component\n */\nexport const mapPackageTags = (\n packageTags?: PackageTagConfig[]\n): TagObject[] => {\n return (packageTags ?? [])\n .filter((tag) => {\n return Boolean(tag.keyword?.label);\n })\n .map((tag) => ({\n ...tag,\n id: tag.keyword?.label!,\n }));\n};\n\n/**\n * Maps keywords to an array of TagObjects, which can be rendered by the PackageTags component\n */\nexport const mapPackageKeywords = (keywords?: string[]): TagObject[] => {\n if (!keywords || keywords.length < 1) return [];\n\n return keywords\n .filter((label) => Boolean(label) && !KEYWORD_IGNORE_LIST.has(label))\n .map((label) => ({\n id: label,\n keyword: {\n label,\n },\n }));\n};\n\n/**\n * Maps packageTags and keywords to a list of TagObjects, using mapPackageTags and mapPackageKeywords\n */\nexport const tagObjectsFrom = ({\n packageTags,\n keywords,\n}: {\n packageTags?: PackageTagConfig[];\n keywords?: string[];\n}): TagObject[] => {\n const tagObjects = new Array<TagObject>();\n const tagLabels = new Set<string>();\n\n for (const tag of [\n ...mapPackageTags(packageTags),\n ...mapPackageKeywords(keywords),\n ]) {\n const label = tag.keyword!.label.toLowerCase();\n if (!tagLabels.has(label)) {\n tagObjects.push(tag);\n tagLabels.add(label);\n }\n }\n\n return tagObjects;\n};\n","import { useMemo } from \"react\";\nimport { useLocation } from \"react-router-dom\";\n\nexport const useQueryParams = () => {\n const { search } = useLocation();\n\n return useMemo(() => new URLSearchParams(search), [search]);\n};\n","import type { Config } from \"../../api/config\";\nimport { useConfig } from \"../../contexts/Config\";\n\nexport const useConfigValue = <T extends keyof Config>(key: T) => {\n const { data } = useConfig();\n return (data ?? {})[key];\n};\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useLocation, useHistory } from \"react-router-dom\";\nimport { Language, TEMP_SUPPORTED_LANGUAGES } from \"../../constants/languages\";\nimport { QUERY_PARAMS } from \"../../constants/url\";\nimport { useQueryParams } from \"../../hooks/useQueryParams\";\n\n// Only supported language atm\nconst defaultLang = Language.TypeScript;\n\nconst LOCAL_KEY = \"preferred-language\";\n\nconst isValidLang = (lang?: string | Language): lang is Language =>\n lang != null && TEMP_SUPPORTED_LANGUAGES.has(lang as Language);\n\nconst getInitialLang = (langFromParams: string | Language): Language => {\n // First, use language from query params in url\n if (isValidLang(langFromParams)) {\n return langFromParams;\n }\n\n // Next check for one stored in localStorage\n try {\n const storedLang = (localStorage.getItem(LOCAL_KEY) ?? \"\") as Language;\n if (isValidLang(storedLang)) return storedLang;\n } catch {\n // Do nothing, we just don't want to crash if localStorage access is blocked.\n }\n\n // Otherwise fallback to a default\n return defaultLang;\n};\n\nexport interface UseLanguageOptions {\n /**\n * Syncs the preferred language to a query param in URL\n */\n updateUrl?: boolean;\n /**\n * Saves the selected language to localStorage on select\n */\n updateSaved?: boolean;\n}\n\nexport const useLanguage = (options: UseLanguageOptions = {}) => {\n const { updateUrl, updateSaved } = options;\n const { pathname, hash } = useLocation();\n const { replace } = useHistory();\n const params = useQueryParams();\n const langFromParams = params.get(QUERY_PARAMS.LANGUAGE) as Language;\n\n // Passed as function to guarantee it runs on hook mount\n const [language, setLanguage] = useState<Language>(() =>\n getInitialLang(langFromParams)\n );\n\n // State subscribes to query param changes\n useEffect(() => {\n if (isValidLang(langFromParams) && langFromParams !== language) {\n setLanguage(langFromParams);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [langFromParams]);\n\n // Syncs language changes to URL if updateUrl = true\n useEffect(() => {\n if (langFromParams !== language && updateUrl) {\n params.set(QUERY_PARAMS.LANGUAGE, language);\n replace({ pathname, hash, search: params.toString() });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [language, updateUrl]);\n\n const update = useCallback(\n (val: Language) => {\n setLanguage(val);\n\n if (updateSaved) {\n try {\n localStorage.setItem(LOCAL_KEY, val);\n } catch {\n // OK to fail silently\n }\n }\n },\n [updateSaved]\n );\n\n return useMemo(() => [language, update] as const, [language, update]);\n};\n","export enum PackageCardType {\n Wide = \"wide\",\n}\n","import { createTestIds } from \"../../util/createTestIds\";\n\nconst testIds = createTestIds(\"packageCard\", [\n \"author\",\n \"description\",\n \"downloads\",\n \"languages\",\n \"published\",\n \"title\",\n \"version\",\n \"comment\",\n \"wideContainer\",\n] as const);\n\nexport default testIds;\n","import { Text, Tooltip } from \"@chakra-ui/react\";\nimport { formatDistanceToNowStrict } from \"date-fns\";\nimport { FunctionComponent, ReactChild } from \"react\";\nimport { useStats } from \"../../contexts/Stats\";\nimport { getSearchPath } from \"../../util/url\";\nimport { NavLink } from \"../NavLink\";\nimport { Time } from \"../Time\";\nimport { usePackageCard } from \"./PackageCard\";\nimport testIds from \"./testIds\";\n\ninterface DetailProps {\n \"data-testid\": string;\n\n tooltip?: string;\n value: ReactChild;\n}\n\nconst Detail: FunctionComponent<DetailProps> = ({\n \"data-testid\": dataTestid,\n tooltip,\n value,\n}) => (\n <Tooltip hasArrow isDisabled={!tooltip} label={tooltip} placement=\"left\">\n {/* zIndex required to allow tooltip to display due to card link overlay */}\n <Text data-testid={dataTestid} fontSize=\"xs\" zIndex={1}>\n {value}\n </Text>\n </Tooltip>\n);\n\nexport const Details: FunctionComponent = () => {\n const {\n author,\n metadata: { date },\n name,\n } = usePackageCard();\n\n const { data } = useStats();\n const downloads: number | undefined = data?.packages?.[name]?.downloads?.npm;\n\n const authorName = typeof author === \"string\" ? author : author.name;\n const publishDate = new Date(date);\n\n return (\n <>\n {downloads !== undefined && (\n <Detail\n data-testid={testIds.downloads}\n tooltip=\"Download numbers are periodically sourced from the npm registry\"\n value={`${downloads.toLocaleString()} weekly downloads`}\n />\n )}\n <Detail\n data-testid={testIds.published}\n value={\n <Time\n date={publishDate}\n fontSize=\"xs\"\n formattedDate={formatDistanceToNowStrict(publishDate, {\n addSuffix: true,\n })}\n />\n }\n />\n <Detail\n data-testid={testIds.author}\n value={\n <>\n By{\" \"}\n <NavLink\n color=\"blue.500\"\n to={getSearchPath({\n query: authorName,\n })}\n >\n {authorName}\n </NavLink>\n </>\n }\n />\n </>\n );\n};\n","import { Text } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport testIds from \"./testIds\";\n\nexport const EditorsNote: FunctionComponent<{ comment?: string }> = ({\n comment,\n}) => {\n return (\n <Text\n data-testid={testIds.comment}\n fontSize=\"md\"\n lineHeight=\"tall\"\n noOfLines={4}\n >\n <Text as=\"span\" color=\"blue.500\" fontWeight=\"bold\">\n Editor&apos;s note:{\" \"}\n </Text>\n {comment}\n </Text>\n );\n};\n","import {\n Flex,\n Heading as ChakraHeading,\n LinkOverlay,\n Text,\n} from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { eventName } from \"../../contexts/Analytics\";\nimport { useLanguage } from \"../../hooks/useLanguage\";\nimport { getPackagePath } from \"../../util/url\";\nimport { CDKTypeBadge } from \"../CDKType\";\nimport { EditorsNote } from \"./EditorsNote\";\nimport { usePackageCard } from \"./PackageCard\";\nimport testIds from \"./testIds\";\n\nexport const Heading: FunctionComponent = () => {\n const [currentLanguage] = useLanguage();\n const {\n dataEvent,\n description,\n comment,\n metadata: { constructFramework },\n name,\n version,\n } = usePackageCard();\n\n const cdkType = constructFramework?.name;\n const cdkVersion = constructFramework?.majorVersion;\n\n return (\n <>\n <LinkOverlay\n as={Link}\n data-event={\n dataEvent ? eventName(dataEvent, \"Package Card\", name) : undefined\n }\n to={getPackagePath({\n name,\n version,\n language: currentLanguage,\n })}\n >\n <Flex align=\"center\">\n <CDKTypeBadge majorVersion={cdkVersion} mr={2} name={cdkType} />\n <ChakraHeading\n as=\"h3\"\n color=\"blue.800\"\n data-testid={testIds.title}\n fontSize=\"md\"\n fontWeight=\"bold\"\n wordBreak=\"normal\"\n >\n {name}\n </ChakraHeading>\n </Flex>\n </LinkOverlay>\n {comment ? (\n <EditorsNote comment={comment} />\n ) : (\n <Text\n color=\"blue.800\"\n data-testid={testIds.description}\n fontSize=\"md\"\n lineHeight=\"tall\"\n noOfLines={4}\n >\n {description || \"No description available.\"}\n </Text>\n )}\n </>\n );\n};\n","import { Box } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { highlightsFrom } from \"../../util/package\";\nimport { Highlight as HighlightComponent } from \"../Highlight\";\nimport { usePackageCard } from \"./PackageCard\";\n\nexport const Highlight: FunctionComponent = () => {\n const { packageTags = [] } = usePackageCard()?.metadata ?? {};\n const [highlight] = highlightsFrom(packageTags);\n\n if (!highlight) return null;\n\n return (\n <Box fontSize=\"xs\">\n <HighlightComponent {...highlight} />\n </Box>\n );\n};\n","import type { FunctionComponent } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport {\n Language,\n LANGUAGES,\n LANGUAGE_RENDER_MAP,\n TEMP_SUPPORTED_LANGUAGES,\n} from \"../../constants/languages\";\nimport { getPackagePath } from \"../../util/url\";\nimport { LanguageSupportTooltip } from \"../LanguageSupportTooltip\";\n\nconst sizes = {\n sm: 5,\n md: 6,\n lg: 8,\n};\n\nexport interface PackageLanguagesProps {\n isRounded?: boolean;\n languages?: Partial<Record<Language, unknown>>;\n name: string;\n size?: \"sm\" | \"md\" | \"lg\";\n version: string;\n}\n\nexport const PackageLanguages: FunctionComponent<PackageLanguagesProps> = ({\n isRounded = false,\n languages,\n name: packageName,\n size = \"md\",\n version,\n}) => {\n const targets = Object.keys(languages ?? {}) as Language[];\n return (\n <>\n {Object.entries(LANGUAGE_RENDER_MAP)\n // Ensure entries are always sorted in a stable way\n .sort(\n ([left], [right]) =>\n LANGUAGES.indexOf(left as Language) -\n LANGUAGES.indexOf(right as Language)\n )\n .map(([lang, info]) => {\n const language = lang as Language;\n\n const isSupportedByLibrary =\n language === Language.TypeScript || targets.includes(language);\n\n const isSupportedByConstructHub =\n language === Language.TypeScript || // TypeScript is always supported\n // Otherwise, the language must be supported by ConstructHub\n TEMP_SUPPORTED_LANGUAGES.has(language);\n\n if (!isSupportedByLibrary) return null;\n\n const { name, icon: Icon } = info;\n\n const icon = (\n <Icon\n aria-label={`Supports ${name}`}\n borderRadius={isRounded ? \"50%\" : 0}\n h={sizes[size]}\n opacity={isSupportedByConstructHub ? 1 : 0.2}\n w={sizes[size]}\n />\n );\n\n return (\n <LanguageSupportTooltip key={language} language={language}>\n {isSupportedByConstructHub ? (\n <Link\n aria-label={`View package docs for ${language}`}\n to={getPackagePath({ name: packageName, version, language })}\n >\n {icon}\n </Link>\n ) : (\n icon\n )}\n </LanguageSupportTooltip>\n );\n })}\n </>\n );\n};\n","import type { FunctionComponent } from \"react\";\nimport { PackageLanguages } from \"../PackageLanguages\";\nimport { usePackageCard } from \"./PackageCard\";\n\nexport const Languages: FunctionComponent = () => {\n const pkg = usePackageCard();\n return <PackageLanguages {...pkg} size=\"sm\" />;\n};\n","import { FunctionComponent } from \"react\";\nimport { tagObjectsFrom } from \"../../util/package\";\nimport { PackageTag } from \"../PackageTag\";\nimport { usePackageCard } from \"./PackageCard\";\n\nexport const Tags: FunctionComponent = () => {\n const {\n keywords = [],\n metadata: { packageTags = [] },\n } = usePackageCard();\n\n const tags = tagObjectsFrom({\n packageTags,\n keywords,\n });\n\n return (\n <>\n {tags.slice(0, 10).map(({ id, keyword: { label, color } = {} }) => (\n <PackageTag key={id} value={id} variant={color}>\n {label}\n </PackageTag>\n ))}\n </>\n );\n};\n","import { Flex, Grid, LinkBox, Stack } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { Details } from \"./Details\";\nimport { Heading } from \"./Heading\";\nimport { Highlight } from \"./Highlight\";\nimport { Languages } from \"./Languages\";\nimport { Tags } from \"./Tags\";\nimport testIds from \"./testIds\";\n\nexport const WideCard: FunctionComponent = () => {\n return (\n <LinkBox\n _hover={{\n \"> article\": {\n bg: \"gray.50\",\n },\n }}\n >\n <Grid\n as=\"article\"\n bg=\"white\"\n border=\"base\"\n borderRadius=\"sm\"\n boxShadow=\"base\"\n color=\"blue.800\"\n data-testid={testIds.wideContainer}\n h=\"full\"\n minH=\"12.5rem\"\n templateColumns={{ base: \"1fr\", lg: \"1fr 14rem\" }}\n w=\"full\"\n >\n {/* Top / Left side of card */}\n <Flex\n direction=\"column\"\n justify=\"space-between\"\n p={5}\n sx={{ gap: \"0.5rem\" }}\n >\n <Stack spacing={3}>\n <Heading />\n </Stack>\n\n <Flex align=\"center\" sx={{ gap: \"0.5rem\" }} wrap=\"wrap\">\n <Tags />\n </Flex>\n </Flex>\n\n {/* Bottom / Right side of card */}\n <Flex\n align={{ base: \"end\", lg: \"initial\" }}\n borderLeft={{ lg: \"base\" }}\n borderTop={{ base: \"base\", lg: \"none\" }}\n direction={{ base: \"row\", lg: \"column\" }}\n justify=\"space-between\"\n p={5}\n sx={{ gap: \"0.5rem\" }}\n >\n <Stack spacing={1}>\n <Highlight />\n <Stack spacing={1}>\n <Details />\n </Stack>\n </Stack>\n\n <Stack data-testid={testIds.languages} direction=\"row\" spacing={2}>\n <Languages />\n </Stack>\n </Flex>\n </Grid>\n </LinkBox>\n );\n};\n","import { createContext, FunctionComponent, useContext } from \"react\";\nimport { CatalogPackage } from \"../../api/package/packages\";\nimport { PackageCardType } from \"./constants\";\nimport { WideCard } from \"./WideCard\";\n\nexport interface PackageCardProps {\n \"data-event\"?: string;\n pkg: CatalogPackage;\n variant?: PackageCardType;\n}\n\ninterface PackageCardState extends CatalogPackage {\n comment?: string;\n dataEvent?: string;\n}\n\nconst PackageCardContext = createContext<PackageCardState | null>(null);\n\nexport const usePackageCard = () => useContext(PackageCardContext)!;\n\nexport const PackageCard: FunctionComponent<PackageCardProps> = ({\n \"data-event\": dataEvent,\n pkg,\n variant = PackageCardType.Wide,\n}) => {\n return (\n <PackageCardContext.Provider value={{ ...pkg, dataEvent }}>\n {variant === PackageCardType.Wide && <WideCard />}\n </PackageCardContext.Provider>\n );\n};\n","import { Box, BoxProps, forwardRef } from \"@chakra-ui/react\";\nimport { format } from \"date-fns\";\n\nexport type TimeOptions = {\n date: Date;\n format?: string;\n formattedDate?: string;\n};\n\nexport interface TimeProps extends BoxProps, TimeOptions {}\n\nexport const Time = forwardRef<TimeProps, \"time\">(\n ({ date, format: formatString, formattedDate, ...boxProps }, ref) => {\n return (\n <Box as=\"time\" dateTime={date.toISOString()} ref={ref} {...boxProps}>\n {formattedDate ?? format(date, formatString ?? \"\")}\n </Box>\n );\n }\n);\n\nTime.displayName = \"Time\";\n","import { Stack, Image, Text } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\n\ninterface HighlightProps {\n label: string;\n color?: string;\n icon?: string;\n}\n\nexport const Highlight: FunctionComponent<HighlightProps> = ({\n label,\n color,\n icon,\n}: HighlightProps) => {\n return (\n <Stack align=\"center\" direction=\"row\" spacing={2}>\n <Image alt={`${label} icon`} src={icon} w={4} />\n <Text color={color} fontWeight=\"bold\">\n {label}\n </Text>\n </Stack>\n );\n};\n","import { Tag, TagLabel, TagProps } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { getSearchPath } from \"../../util/url\";\nimport { NavLink } from \"../NavLink\";\n\nexport interface PackageTagProps extends TagProps {\n value: string;\n label?: string;\n zIndex?: string | number;\n}\n\nexport const PackageTag: FunctionComponent<PackageTagProps> = ({\n children,\n value,\n label = value,\n zIndex,\n ...tagProps\n}) => {\n return (\n <NavLink\n aria-label={`Tag: ${label}`}\n to={getSearchPath({ keywords: [value] })}\n zIndex={zIndex}\n >\n <Tag\n _hover={{\n textDecoration: \"underline\",\n }}\n {...tagProps}\n >\n <TagLabel>{children}</TagLabel>\n </Tag>\n </NavLink>\n );\n};\n","import { Tooltip } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport {\n Language,\n LANGUAGE_NAME_MAP,\n TEMP_SUPPORTED_LANGUAGES,\n} from \"../../constants/languages\";\n\nexport interface LanguageSupportTooltipProps {\n language: Language;\n}\n\nexport const LanguageSupportTooltip: FunctionComponent<\n LanguageSupportTooltipProps\n> = ({ children, language }) => {\n const isSupported = TEMP_SUPPORTED_LANGUAGES.has(language);\n const langName = LANGUAGE_NAME_MAP[language];\n\n const message = isSupported\n ? `Click to view documentation in ${langName}`\n : `Documentation support for ${langName} is coming soon!`;\n\n return (\n <Tooltip hasArrow label={message} placement=\"top-start\">\n <span>{children}</span>\n </Tooltip>\n );\n};\n","import { QuestionIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Heading,\n Text,\n Popover,\n PopoverTrigger,\n PopoverBody,\n PopoverArrow,\n PopoverContent,\n useBreakpointValue,\n PlacementWithLogical,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\n\nexport interface FilterHeadingProps {\n name: string;\n hint?: string;\n}\n\nexport const FilterHeading: FunctionComponent<FilterHeadingProps> = ({\n name,\n hint,\n}) => {\n const placement = useBreakpointValue<PlacementWithLogical>({\n base: \"auto\",\n md: \"right\",\n });\n\n return (\n <Flex align=\"center\" mb={1}>\n <Heading as=\"h4\" size=\"sm\" w=\"max-content\">\n {name}\n </Heading>\n {hint ? (\n <Popover colorScheme=\"dark\" placement={placement} strategy=\"fixed\">\n <PopoverTrigger>\n <Flex aria-label={`Hint: ${name}`} as=\"button\" ml={2}>\n <QuestionIcon h={3.5} w={3.5} />\n </Flex>\n </PopoverTrigger>\n <PopoverContent\n bg=\"gray.700\"\n borderRadius=\"base\"\n color=\"white\"\n fontSize=\"sm\"\n mx={{ base: \"1rem\", md: \"initial\" }}\n shadow=\"whiteAlpha.300\"\n >\n <PopoverArrow bg=\"gray.700\" />\n <PopoverBody>\n <Text>{hint}</Text>\n </PopoverBody>\n </PopoverContent>\n </Popover>\n ) : null}\n </Flex>\n );\n};\n","import { createTestIds } from \"../../util/createTestIds\";\n\nexport default createTestIds(\"searchRedesign\", [\n \"page\",\n // Results\n \"searchDetails\",\n \"nextPage\",\n \"prevPage\",\n \"goToPage\",\n // Sorting\n \"sortButton\",\n \"sortDropdown\",\n \"sortItem\",\n // Filters Panel\n \"filtersPanel\",\n \"cdkTypeFilter\",\n \"cdkVersionFilter\",\n \"filterItem\",\n \"languagesFilter\",\n] as const);\n","import { Radio, RadioGroup, Stack, Text } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { FilterHeading, FilterHeadingProps } from \"./FilterHeading\";\nimport testIds from \"./testIds\";\n\nexport interface RadioFilterProps extends FilterHeadingProps {\n \"data-testid\"?: string;\n value?: string;\n onValueChange: (value: string) => void;\n options: {\n display: string;\n value: string;\n }[];\n}\n\nexport const RadioFilter: FunctionComponent<RadioFilterProps> = ({\n \"data-testid\": dataTestid,\n value: checkedValue,\n onValueChange,\n options,\n name,\n hint,\n}) => {\n return (\n <Stack data-testid={dataTestid} spacing={1}>\n <FilterHeading hint={hint} name={name} />\n <RadioGroup onChange={onValueChange} value={checkedValue}>\n <Stack spacing={1}>\n {options.map(({ display, value }) => (\n <Radio key={value} value={value}>\n <Text\n color=\"gray.600\"\n data-testid={testIds.filterItem}\n data-value={value}\n isTruncated\n >\n {display}\n </Text>\n </Radio>\n ))}\n </Stack>\n </RadioGroup>\n </Stack>\n );\n};\n","import { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport type { QueryParamKey } from \"../../constants/url\";\n\nconst LIMITS = [25, 50, 75, 100];\nexport const LIMIT = LIMITS[0];\n\nexport type SearchQueryParam = Extract<QueryParamKey, \"offset\" | \"q\">;\n\nexport const SORT_RENDER_MAP = {\n [CatalogSearchSort.NameAsc]: \"A-Z\",\n [CatalogSearchSort.NameDesc]: \"Z-A\",\n [CatalogSearchSort.PublishDateAsc]: \"Oldest first\",\n [CatalogSearchSort.PublishDateDesc]: \"Newest first\",\n [CatalogSearchSort.DownloadsDesc]: \"Most downloads\",\n [CatalogSearchSort.DownloadsAsc]: \"Least downloads\",\n};\n","export const toNum = (val: string) => {\n const result = parseInt(val);\n\n if (`${result}` === \"NaN\") {\n return 0;\n }\n\n return result;\n};\n\nexport const parseQueryArray = <T extends string>(\n queryString: string | null\n) => {\n if (!queryString) return [];\n\n return decodeURIComponent(queryString).split(\",\") as T[];\n};\n","/**\n * @fileoverview Exposes page-level state and setters to all components in the new SearchResults View.\n */\nimport {\n createContext,\n FunctionComponent,\n useContext,\n useEffect,\n useMemo,\n} from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { CDKType } from \"../../constants/constructs\";\nimport { Language } from \"../../constants/languages\";\nimport { QUERY_PARAMS } from \"../../constants/url\";\nimport {\n UseCatalogSearchReturn,\n useCatalogSearch,\n} from \"../../hooks/useCatalogSearch\";\nimport { useQueryParams } from \"../../hooks/useQueryParams\";\nimport { LIMIT } from \"../SearchRedesign/constants\";\nimport { parseQueryArray, toNum } from \"./util\";\n\nexport interface SearchState {\n limit: number;\n offset: number;\n query: string;\n searchAPI: UseCatalogSearchReturn;\n}\n\nconst SearchStateContext = createContext<SearchState | undefined>(undefined);\n\n/**\n * A hook to access Search Page specific state. This can only be in descendants of the new Search Page\n * and will otherwise throw an error.\n */\nexport const useSearchState = () => {\n const state = useContext(SearchStateContext);\n\n if (!state) {\n throw new Error(\n `This hook must be called in a child of <SearchStateProvider />`\n );\n }\n\n return state;\n};\n\nexport const SearchStateProvider: FunctionComponent = ({ children }) => {\n const queryParams = useQueryParams();\n\n const offset = toNum(queryParams.get(QUERY_PARAMS.OFFSET) ?? \"0\");\n\n const query = decodeURIComponent(\n queryParams.get(QUERY_PARAMS.SEARCH_QUERY) ?? \"\"\n );\n\n const languages: Language[] = parseQueryArray(\n queryParams.get(QUERY_PARAMS.LANGUAGES)\n );\n const tagQuery = queryParams.get(QUERY_PARAMS.TAGS);\n const tags = useMemo(() => parseQueryArray(tagQuery), [tagQuery]);\n\n const keywordQuery = queryParams.get(QUERY_PARAMS.KEYWORDS);\n const keywords = useMemo(() => parseQueryArray(keywordQuery), [keywordQuery]);\n\n const sort = (queryParams.get(QUERY_PARAMS.SORT) ?? undefined) as\n | CatalogSearchSort\n | undefined;\n\n const cdkType =\n (queryParams.get(QUERY_PARAMS.CDK_TYPE) as CDKType) ?? undefined;\n\n const cdkMajorParam = queryParams.get(QUERY_PARAMS.CDK_MAJOR);\n const cdkMajor = cdkMajorParam ? toNum(cdkMajorParam) : undefined;\n\n const searchAPI = useCatalogSearch({\n defaultCdkMajor: cdkMajor,\n defaultCdkType: cdkType,\n defaultKeywords: keywords,\n defaultLanguages: languages,\n defaultQuery: query,\n defaultSort: sort,\n defaultTags: tags,\n });\n\n useEffect(() => {\n if (query !== searchAPI.query) {\n searchAPI.setQuery(query);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [query]);\n\n useEffect(() => {\n if (keywords.some((k) => !searchAPI.keywords.includes(k))) {\n searchAPI.setKeywords(keywords);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [keywords]);\n\n useEffect(() => {\n if (tags.some((t) => !searchAPI.tags.includes(t))) {\n searchAPI.setTags(tags);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [tags]);\n\n return (\n <SearchStateContext.Provider\n value={{\n limit: LIMIT,\n offset,\n query,\n searchAPI,\n }}\n >\n {children}\n </SearchStateContext.Provider>\n );\n};\n","import { FunctionComponent, useMemo } from \"react\";\nimport { CatalogConstructFrameworkMeta } from \"../../api/catalog-search\";\nimport { CDKType, CDKTYPE_NAME_MAP } from \"../../constants/constructs\";\nimport { useSearchContext } from \"../../contexts/Search\";\nimport { RadioFilter } from \"./RadioFilter\";\nimport { useSearchState } from \"./SearchState\";\nimport testIds from \"./testIds\";\n\ntype CDKOptions = Partial<{\n [key in CDKType]: CatalogConstructFrameworkMeta & {\n display: string;\n value: key;\n };\n}>;\n\nexport const CDKFilter: FunctionComponent = () => {\n const { cdkType, setCdkType, cdkMajor, setCdkMajor } =\n useSearchState().searchAPI;\n const searchAPI = useSearchContext()!;\n\n // Options with less than one package will be omitted\n const cdkOptions = useMemo(() => {\n const cdkTypes = searchAPI.constructFrameworks;\n const options = Object.entries(cdkTypes).reduce((opts, [name, meta]) => {\n if (meta.pkgCount < 1) {\n return opts;\n }\n\n return {\n ...opts,\n [name]: {\n display: CDKTYPE_NAME_MAP[name as CDKType],\n value: name,\n ...meta,\n },\n };\n }, {});\n\n return Object.keys(options).length ? (options as CDKOptions) : undefined;\n }, [searchAPI]);\n\n const majorsOptions = useMemo(() => {\n if (!cdkOptions || !cdkType) return undefined;\n const majorVersions = cdkOptions[cdkType]?.majorVersions;\n\n if (!majorVersions) return undefined;\n\n return [...majorVersions]\n .sort((a, b) => a - b)\n .map((value) => ({\n value: value.toString(),\n display: `${CDKTYPE_NAME_MAP[cdkType]} v${value}`,\n }));\n }, [cdkOptions, cdkType]);\n\n if (!cdkOptions) {\n return null;\n }\n\n const onCdkTypeChange = (type: string) => {\n const cdk = type as CDKType;\n setCdkMajor(undefined);\n setCdkType(type ? cdk : undefined);\n };\n\n const onCdkMajorChange = (major: string) => {\n if (!major) {\n setCdkMajor(undefined);\n return;\n }\n\n const majorNum = parseInt(major, 10);\n\n setCdkMajor(majorNum);\n };\n\n return (\n <>\n <RadioFilter\n data-testid={testIds.cdkTypeFilter}\n hint=\"Choose the right CDK for your IaC technology: AWS CDK for AWS CloudFormation, CDKtf for Terraform, or CDK8s for Kubernetes.\"\n name=\"CDK Type\"\n onValueChange={onCdkTypeChange}\n options={[\n { display: \"Any CDK Type\", value: \"\" },\n ...Object.values(cdkOptions),\n ]}\n value={cdkType ?? \"\"}\n />\n {/* No point in showing major versions if only a single one is available */}\n {!!(majorsOptions && majorsOptions.length > 1) && (\n <RadioFilter\n data-testid={testIds.cdkVersionFilter}\n hint=\"Choose the major version of the CDK you're using to see only constructs that will work with that version.\"\n name=\"CDK Major Version\"\n onValueChange={onCdkMajorChange}\n options={[\n { display: \"Any Major Version\", value: \"\" },\n ...majorsOptions,\n ]}\n value={cdkMajor?.toString() ?? \"\"}\n />\n )}\n </>\n );\n};\n","import { ChevronDownIcon, ChevronUpIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Button,\n Collapse,\n Checkbox,\n Stack,\n Text,\n Tooltip,\n useDisclosure,\n} from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { FilterHeading, FilterHeadingProps } from \"./FilterHeading\";\nimport testIds from \"./testIds\";\n\ninterface CheckboxOption {\n display: string;\n value: string;\n isDisabled?: boolean;\n disabledHint?: string;\n}\n\ninterface CheckboxItemProps extends CheckboxOption {\n onChange: () => void;\n isChecked: boolean;\n}\n\nexport interface CheckboxFilterProps extends FilterHeadingProps {\n /**\n * Test ID to select checkbox in tests\n */\n \"data-testid\"?: string;\n /**\n * Number of items that can be initially shown\n */\n initialItemCount?: number;\n /**\n * Defines checkbox items\n */\n options: CheckboxOption[];\n /**\n * Selected values\n */\n values: string[];\n /**\n * Callback triggered when an item is clicked\n */\n onValueChange: (value: string) => void;\n}\n\nconst CheckboxItem: FunctionComponent<CheckboxItemProps> = ({\n display,\n value,\n isDisabled,\n disabledHint,\n isChecked,\n onChange,\n}) => (\n <Checkbox\n isChecked={isChecked}\n isDisabled={isDisabled}\n key={value}\n onChange={onChange}\n >\n <Tooltip\n hasArrow\n isDisabled={!isDisabled && !disabledHint}\n label={disabledHint}\n placement=\"right\"\n >\n <Text\n color=\"gray.600\"\n data-testid={testIds.filterItem}\n data-value={value}\n isTruncated\n >\n {display}\n </Text>\n </Tooltip>\n </Checkbox>\n);\n\nexport const CheckboxFilter: FunctionComponent<CheckboxFilterProps> = ({\n \"data-testid\": dataTestid,\n initialItemCount,\n hint,\n name,\n options,\n values: checkedValues,\n onValueChange,\n}) => {\n const collapse = useDisclosure();\n\n const getOnChange = (value: string) => () => {\n onValueChange(value);\n };\n\n let alwaysShow: typeof options = options;\n let showWhenExpanded: typeof options = [];\n\n if (initialItemCount) {\n alwaysShow = options.slice(0, initialItemCount);\n showWhenExpanded = options.slice(initialItemCount, options.length);\n }\n\n const isExpandible = showWhenExpanded.length > 0;\n\n return (\n <Flex data-testid={dataTestid} direction=\"column\">\n <FilterHeading hint={hint} name={name} />\n <Stack mt={1} spacing={1}>\n {alwaysShow.map((item) => (\n <CheckboxItem\n {...item}\n isChecked={checkedValues.includes(item.value)}\n key={item.value}\n onChange={getOnChange(item.value)}\n />\n ))}\n {isExpandible && (\n <Collapse animateOpacity in={collapse.isOpen} unmountOnExit>\n <Stack spacing={1}>\n {showWhenExpanded.map((item) => (\n <CheckboxItem\n {...item}\n isChecked={checkedValues.includes(item.value)}\n key={item.value}\n onChange={getOnChange(item.value)}\n />\n ))}\n </Stack>\n </Collapse>\n )}\n </Stack>\n {isExpandible && (\n <Flex align=\"start\" mt={1}>\n <Button\n color=\"gray.600\"\n fontWeight=\"normal\"\n leftIcon={collapse.isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}\n onClick={collapse.onToggle}\n size=\"sm\"\n textAlign=\"left\"\n variant=\"link\"\n w=\"auto\"\n >\n {collapse.isOpen\n ? `Show fewer options (${alwaysShow.length})`\n : `Show more options (${showWhenExpanded.length})`}\n </Button>\n </Flex>\n )}\n </Flex>\n );\n};\n","import { FunctionComponent, useMemo } from \"react\";\nimport { useSearchContext } from \"../../contexts/Search\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\nimport { useSearchState } from \"./SearchState\";\nimport testIds from \"./testIds\";\n\nexport const KeywordsFilter: FunctionComponent = () => {\n const { keywords, setKeywords } = useSearchState().searchAPI;\n const keywordMap = useSearchContext()!.keywords;\n\n const onKeywordChange = (keyword: string) => {\n setKeywords(\n keywords.includes(keyword)\n ? keywords.filter((k) => k !== keyword)\n : [...keywords, keyword]\n );\n };\n\n const keywordOptions = useMemo(() => {\n const baseOptions = [...keywordMap.entries()]\n .sort(([, count1], [, count2]) => {\n return count1 < count2 ? 1 : -1;\n })\n .filter(([keyword]) => !keywords.includes(keyword))\n .map(([keyword]) => ({\n display: keyword,\n value: keyword,\n }))\n .slice(0, 25);\n\n const keywordsNotInOptions = keywords.filter(\n (k) => !baseOptions.some((opt) => opt.value === k)\n );\n\n return [\n ...keywordsNotInOptions.map((k) => ({ display: k, value: k })),\n ...baseOptions,\n ];\n }, [keywordMap, keywords]);\n\n return (\n <CheckboxFilter\n data-testid={testIds.languagesFilter}\n hint=\"Focus the results by choosing one or more keywords reflecting the kind of construct you're looking for. Keywords are provided by construct authors.\"\n initialItemCount={5}\n name=\"Keywords\"\n onValueChange={onKeywordChange}\n options={keywordOptions}\n values={keywords}\n />\n );\n};\n","import { FunctionComponent } from \"react\";\nimport {\n Language,\n LANGUAGE_NAME_MAP,\n TEMP_SUPPORTED_LANGUAGES,\n} from \"../../constants/languages\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\nimport { useSearchState } from \"./SearchState\";\nimport testIds from \"./testIds\";\n\nconst languageOptions = Object.entries(LANGUAGE_NAME_MAP)\n .map(([key, value]) => ({\n display: value,\n value: key,\n ...(TEMP_SUPPORTED_LANGUAGES.has(key as Language)\n ? { isDisabled: false }\n : {\n isDisabled: true,\n disabledHint: `${\n LANGUAGE_NAME_MAP[key as Language]\n } support is coming soon!`,\n }),\n }))\n .sort((l1, l2) => {\n // Push disabled languages to back of list\n return l1.isDisabled > l2.isDisabled ? 1 : -1;\n });\n\nexport const LanguageFilter: FunctionComponent = () => {\n const { languages, setLanguages } = useSearchState().searchAPI;\n\n const onLanguagesChange = (lang: string) => {\n const language = lang as Language;\n\n setLanguages(\n languages.includes(language)\n ? languages.filter((l) => l !== language)\n : [...languages, language]\n );\n };\n\n return (\n <CheckboxFilter\n data-testid={testIds.languagesFilter}\n hint=\"Choose one or more languages. Results include constructs for use with at least one of the selected languages.\"\n name=\"Programming Language\"\n onValueChange={onLanguagesChange}\n options={languageOptions}\n values={languages}\n />\n );\n};\n","import { FunctionComponent } from \"react\";\nimport { PackageTagConfig } from \"../../api/config\";\nimport { useConfigValue } from \"../../hooks/useConfigValue\";\nimport { CheckboxFilter } from \"./CheckboxFilter\";\nimport { useSearchState } from \"./SearchState\";\n\ninterface FilterGroups {\n [group: string]: PackageTagConfig[];\n}\n\nexport const TagFilter: FunctionComponent = () => {\n const filterableTags =\n useConfigValue(\"packageTags\")?.filter((tag) => Boolean(tag.searchFilter)) ??\n [];\n\n const tagFilterGroups: FilterGroups = filterableTags.reduce(\n (accum: FilterGroups, tag: PackageTagConfig): FilterGroups => {\n const groupName = tag.searchFilter?.groupBy;\n if (groupName) {\n return {\n ...accum,\n [groupName]: [...(accum[groupName] ?? []), tag],\n };\n }\n return accum;\n },\n {}\n );\n\n const { tags, setTags } = useSearchState().searchAPI;\n\n const onTagsChange = (tag: string) => {\n setTags(\n tags.includes(tag) ? tags.filter((t) => t !== tag) : [...tags, tag]\n );\n };\n\n return (\n <>\n {Object.entries(tagFilterGroups).map(([title, tagItems]) => {\n return (\n <CheckboxFilter\n key={title}\n name={title}\n onValueChange={onTagsChange}\n options={tagItems.map((tag) => {\n return {\n display: tag.searchFilter!.display,\n value: tag.id,\n };\n })}\n values={tags}\n />\n );\n })}\n </>\n );\n};\n","import { Heading, Stack } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { Card } from \"../../components/Card\";\nimport { CDKFilter } from \"./CDKFilter\";\nimport { KeywordsFilter } from \"./KeywordsFilter\";\nimport { LanguageFilter } from \"./LanguageFilter\";\nimport { TagFilter } from \"./TagFilter\";\nimport testIds from \"./testIds\";\n\nexport interface FilterPanelProps {}\n\n// Header height + section padding\nconst TOP_OFFSET = \"5.75rem\";\n\n/**\n * The desktop Resolution Filter Panel\n */\nexport const FilterPanel: FunctionComponent<FilterPanelProps> = () => {\n return (\n <Card\n borderRadius=\"none\"\n boxShadow=\"none\"\n data-testid={testIds.filtersPanel}\n display={{ base: \"none\", md: \"flex\" }}\n maxH={`calc(100vh - ${TOP_OFFSET} - 1.25rem)`}\n maxW=\"23rem\"\n minW=\"100%\"\n overflow=\"hidden auto\"\n p={4}\n pos=\"sticky\"\n top={TOP_OFFSET}\n zIndex=\"docked\"\n >\n <Stack color=\"blue.800\" h=\"max-content\" spacing={4} top={4}>\n <Heading as=\"h3\" size=\"sm\">\n Filters\n </Heading>\n\n <CDKFilter />\n\n <LanguageFilter />\n\n <TagFilter />\n\n <KeywordsFilter />\n </Stack>\n </Card>\n );\n};\n","import { Center, Spinner } from \"@chakra-ui/react\";\nimport { FunctionComponent, memo } from \"react\";\nimport { CatalogPackage } from \"../../api/package/packages\";\nimport { PackageCardType } from \"../PackageCard\";\nimport { WideCardList } from \"./WideCardList\";\n\nconst listViews = {\n [PackageCardType.Wide]: WideCardList,\n};\n\nexport interface PackageListViewProps {\n items: CatalogPackage[];\n}\n\nexport interface PackageListProps extends Partial<PackageListViewProps> {\n cardView?: PackageCardType;\n loading?: boolean;\n title?: string;\n}\n\nexport const PackageList: FunctionComponent<PackageListProps> = memo(\n ({\n cardView = PackageCardType.Wide,\n items,\n loading,\n // title,\n }) => {\n if (loading || !items) {\n return (\n <Center>\n <Spinner size=\"xl\" />\n </Center>\n );\n }\n\n const View = listViews[cardView];\n\n return <View items={items} />;\n }\n);\n\nPackageList.displayName = \"PackageList\";\n","import { Stack } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { PackageCard, PackageCardType } from \"../PackageCard\";\nimport { PackageListViewProps } from \"./PackageList\";\n\nexport const WideCardList: FunctionComponent<PackageListViewProps> = ({\n items,\n}) => {\n return (\n <Stack spacing={4}>\n {items.map((pkg) => (\n <PackageCard\n key={`${pkg.name}-${pkg.version}`}\n pkg={pkg}\n variant={PackageCardType.Wide}\n />\n ))}\n </Stack>\n );\n};\n","import { IconButton, IconProps } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { Link } from \"react-router-dom\";\n\nexport interface ArrowButtonProps {\n \"data-testid\"?: string;\n icon: FunctionComponent<IconProps>;\n offset?: number;\n getPageUrl: (params: { offset: number }) => string;\n}\n\nexport const ArrowButton: FunctionComponent<ArrowButtonProps> = ({\n \"data-testid\": dataTestid,\n icon: Icon,\n offset,\n getPageUrl,\n}) => {\n const label = `Page ${offset} link`;\n\n const props = {\n \"aria-label\": label,\n borderRadius: \"md\",\n borderColor: \"blue.500\",\n colorScheme: \"blue\",\n \"data-testid\": dataTestid,\n icon: <Icon color=\"blue.500\" h={5} w={5} />,\n mx: 2,\n h: 10,\n w: 10,\n variant: \"outline\",\n };\n\n if (offset !== undefined) {\n return <IconButton {...props} as={Link} to={getPageUrl({ offset })} />;\n }\n\n return <IconButton {...props} disabled />;\n};\n","import { Flex, Input, Text } from \"@chakra-ui/react\";\nimport {\n FormEventHandler,\n FunctionComponent,\n SyntheticEvent,\n useEffect,\n useState,\n} from \"react\";\nimport { useHistory } from \"react-router-dom\";\n\nexport interface GoToPageProps {\n \"data-testid\"?: string;\n pageLimit: number;\n offset: number;\n getPageUrl: (params: { offset: number }) => string;\n}\n\nexport const GoToPage: FunctionComponent<GoToPageProps> = ({\n \"data-testid\": dataTestid,\n pageLimit,\n offset,\n getPageUrl,\n}) => {\n const [inputValue, setInputValue] = useState((offset + 1).toString());\n const { push } = useHistory();\n\n useEffect(() => {\n setInputValue((offset + 1).toString());\n }, [offset]);\n\n const onInputChange = (e: SyntheticEvent<HTMLInputElement>) => {\n e.preventDefault();\n setInputValue((e.target as HTMLInputElement).value);\n };\n\n const onSubmit: FormEventHandler<HTMLInputElement> = (e) => {\n e.preventDefault();\n push(getPageUrl({ offset: parseInt(inputValue) - 1 }));\n };\n\n return (\n <Flex align=\"center\" as=\"form\" mx={2} onSubmit={onSubmit}>\n <Input\n colorScheme=\"blue\"\n data-testid={dataTestid}\n h={10}\n max={pageLimit + 1}\n min={1}\n name=\"page\"\n onChange={onInputChange}\n p={0}\n textAlign=\"center\"\n type=\"number\"\n value={inputValue}\n w={10}\n />\n <Text ml={2} w=\"max-content\">\n of {pageLimit + 1}\n </Text>\n </Flex>\n );\n};\n","import { ChevronLeftIcon, ChevronRightIcon } from \"@chakra-ui/icons\";\nimport { Stack } from \"@chakra-ui/react\";\nimport type { FunctionComponent } from \"react\";\nimport { ArrowButton } from \"./ArrowButton\";\nimport { GoToPage } from \"./GoToPage\";\nimport testIds from \"./testIds\";\n\nexport interface PageControlsProps {\n offset: number;\n pageLimit: number;\n getPageUrl: (params: { offset?: number }) => string;\n}\n\nexport const PageControls: FunctionComponent<PageControlsProps> = ({\n offset,\n getPageUrl,\n pageLimit,\n}) => {\n const nextOffset = offset < pageLimit ? offset + 1 : undefined;\n const prevOffset = offset > 0 ? offset - 1 : undefined;\n\n return (\n <Stack\n align=\"center\"\n direction=\"row\"\n justify=\"space-between\"\n maxW=\"18rem\"\n mx=\"auto\"\n spacing={4}\n w=\"full\"\n >\n <ArrowButton\n data-testid={testIds.prevPage}\n getPageUrl={getPageUrl}\n icon={ChevronLeftIcon}\n offset={prevOffset}\n />\n <GoToPage\n data-testid={testIds.goToPage}\n getPageUrl={getPageUrl}\n offset={offset}\n pageLimit={pageLimit}\n />\n <ArrowButton\n data-testid={testIds.nextPage}\n getPageUrl={getPageUrl}\n icon={ChevronRightIcon}\n offset={nextOffset}\n />\n </Stack>\n );\n};\n","import { Text } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport testIds from \"./testIds\";\n\nexport interface SearchDetailsProps {\n limit: number;\n offset: number;\n count: number;\n filtered: boolean;\n query?: string;\n}\n\nconst Em: FunctionComponent = ({ children }) => (\n <Text as=\"strong\" color=\"gray.700\">\n {children}\n </Text>\n);\n\nconst Count: FunctionComponent<{\n first: number;\n count: number;\n last: number;\n}> = ({ first, count, last }) => {\n if (!first && last >= count) {\n return (\n <>\n <Em>{count}</Em> of <Em>{count}</Em>\n </>\n );\n }\n\n return (\n <>\n <Em>\n {count ? first + 1 : count} - {last > count ? count : last}\n </Em>{\" \"}\n of <Em>{count}</Em>\n </>\n );\n};\n\nexport const SearchDetails: FunctionComponent<SearchDetailsProps> = ({\n limit,\n offset,\n count,\n filtered,\n query,\n}) => {\n const first = limit * offset;\n const last = first + limit;\n const hasResults = count > 0;\n\n return (\n <Text data-testid={testIds.searchDetails}>\n {hasResults ? (\n <>\n Displaying <Count count={count} first={first} last={last} />{\" \"}\n {filtered ? \"search results\" : \"constructs\"}\n </>\n ) : (\n <>{filtered ? \"There were no search results\" : \"No constructs found\"}</>\n )}\n {query && (\n <>\n {\" for \"}\n <Em>{query}</Em>\n </>\n )}\n .{!hasResults && filtered && <> Try a different term.</>}\n </Text>\n );\n};\n","import { FunctionComponent } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { SORT_RENDER_MAP } from \"./constants\";\nimport { RadioFilter } from \"./RadioFilter\";\nimport { useSearchState } from \"./SearchState\";\n\nexport const SortFilter: FunctionComponent = () => {\n const { sort, setSort } = useSearchState().searchAPI;\n\n const onSortChange = (newSort: string) => {\n setSort(newSort ? (newSort as CatalogSearchSort) : undefined);\n };\n\n return (\n <RadioFilter\n hint=\"Sets the order of search results\"\n name=\"Sorted By\"\n onValueChange={onSortChange}\n options={[\n { display: \"Relevance\", value: \"\" },\n ...Object.entries(SORT_RENDER_MAP).map(([value, display]) => ({\n display,\n value,\n })),\n ]}\n value={sort ?? \"\"}\n />\n );\n};\n","import { ChevronDownIcon } from \"@chakra-ui/icons\";\nimport {\n Button,\n Drawer,\n Stack,\n DrawerBody,\n DrawerHeader,\n DrawerOverlay,\n DrawerContent,\n DrawerCloseButton,\n useDisclosure,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { CDKFilter } from \"./CDKFilter\";\nimport { KeywordsFilter } from \"./KeywordsFilter\";\nimport { LanguageFilter } from \"./LanguageFilter\";\nimport { SortFilter } from \"./SortFilter\";\nimport { TagFilter } from \"./TagFilter\";\n\n/**\n * The mobile filter Drawer (Bottomsheet in iOS terminology)\n */\nexport const SortAndFilterDrawer: FunctionComponent = () => {\n const drawer = useDisclosure();\n return (\n <>\n <Button\n colorScheme=\"blue\"\n display={{ md: \"none\" }}\n onClick={drawer.onOpen}\n rightIcon={<ChevronDownIcon />}\n variant=\"link\"\n >\n Sorting and Filters\n </Button>\n <Drawer {...drawer} placement=\"bottom\">\n <DrawerOverlay />\n\n <DrawerContent color=\"blue.800\" maxH=\"full\">\n <DrawerHeader borderBottom=\"base\">Sorting and Filters</DrawerHeader>\n\n <DrawerCloseButton />\n\n <DrawerBody>\n <Stack color=\"blue.800\" pb={4} spacing={4}>\n <SortFilter />\n\n <CDKFilter />\n\n <LanguageFilter />\n\n <TagFilter />\n\n <KeywordsFilter />\n </Stack>\n </DrawerBody>\n </DrawerContent>\n </Drawer>\n </>\n );\n};\n","import { ChevronDownIcon } from \"@chakra-ui/icons\";\nimport {\n Flex,\n Text,\n Menu,\n MenuButton,\n MenuList,\n MenuItem,\n Button,\n} from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { CatalogSearchSort } from \"../../api/catalog-search/constants\";\nimport { SORT_RENDER_MAP } from \"./constants\";\nimport { useSearchState } from \"./SearchState\";\nimport testIds from \"./testIds\";\n\nexport const SortedBy: FunctionComponent = () => {\n const { searchAPI } = useSearchState();\n const { sort, setSort } = searchAPI;\n\n const selected = sort ? SORT_RENDER_MAP[sort] : \"Relevance\";\n\n return (\n <Flex align=\"center\">\n <Text>Sorted by</Text>\n <Menu>\n <MenuButton\n as={Button}\n color=\"blue.500\"\n data-testid={testIds.sortButton}\n ml={2}\n pl={2} // For some reason, the px shorthand doesn't work on this Button\n pr={2}\n py={1}\n rightIcon={<ChevronDownIcon />}\n variant=\"link\"\n >\n {selected}\n </MenuButton>\n <MenuList data-testid={testIds.sortDropdown} minW=\"180\" zIndex=\"sticky\">\n <MenuItem\n data-testid={testIds.sortItem}\n data-value=\"\"\n key=\"Relevance\"\n onClick={() => setSort(undefined)}\n >\n Relevance\n </MenuItem>\n {Object.entries(SORT_RENDER_MAP).map(([value, display]) => (\n <MenuItem\n data-testid={testIds.sortItem}\n data-value={value}\n key={value}\n onClick={() => setSort(value as CatalogSearchSort)}\n >\n {display}\n </MenuItem>\n ))}\n </MenuList>\n </Menu>\n </Flex>\n );\n};\n","import { Box, Stack } from \"@chakra-ui/react\";\nimport { FunctionComponent, useEffect, useRef } from \"react\";\nimport { useHistory } from \"react-router-dom\";\nimport { PackageList } from \"../../components/PackageList\";\nimport { Page } from \"../../components/Page\";\nimport { SearchBar } from \"../../components/SearchBar\";\nimport { useCatalogResults } from \"../../hooks/useCatalogResults\";\nimport { getSearchPath } from \"../../util/url\";\nimport { SearchQueryParam } from \"../SearchRedesign/constants\";\nimport { PageControls } from \"./PageControls\";\nimport { SearchDetails } from \"./SearchDetails\";\nimport { useSearchState } from \"./SearchState\";\nimport { SortAndFilterDrawer } from \"./SortAndFilterDrawer\";\nimport { SortedBy } from \"./SortedBy\";\n\nexport const SearchResults: FunctionComponent = () => {\n const isFirstRender = useRef(true);\n const { push } = useHistory();\n\n const { query, searchAPI, offset, limit } = useSearchState();\n const { keywords, languages, sort, cdkType, cdkMajor, onSearch, tags } =\n searchAPI;\n\n const { page, pageLimit, results } = useCatalogResults({\n offset,\n limit,\n query,\n keywords,\n languages,\n cdkMajor,\n cdkType,\n sort,\n tags,\n });\n\n const getUrl = (\n params: Partial<{ [key in SearchQueryParam]: number | string }>\n ) => {\n return getSearchPath({\n cdkMajor,\n cdkType,\n keywords,\n query: (params.q ?? query) as string,\n languages,\n sort,\n offset: params.offset ?? offset,\n tags,\n });\n };\n\n // Resets the page number to 1 if query param offset is below 0, or to the last page if offset is higher than page count\n useEffect(() => {\n // If the query has results but the page has nothing to show...\n if (results.length && (offset < 0 || offset > pageLimit)) {\n // Handle an out of bounds offset\n if (offset < 0) {\n push(getUrl({ offset: 0 }));\n } else {\n // Offset is too large, just take last page\n push(getUrl({ offset: pageLimit }));\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [results, offset, pageLimit]);\n\n // Reset offset and update url when query, filters, or sort change\n // We want to avoid doing this on first render / when a user directly navigates to a search URL\n // so we keep a ref to prevent this\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n } else {\n // Trigger a history replace rather than push to avoid bloating browser history\n onSearch({ replace: true });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [sort, keywords, languages, cdkType, cdkMajor, tags]);\n\n // Scroll to top on page change\n useEffect(() => {\n window.scrollTo(0, 0);\n }, [page]);\n\n return (\n <Page\n meta={{\n title: query || \"Search\",\n description: query\n ? `${results.length} results for ${query} at Construct Hub`\n : \"Search reusable components for your cloud application\",\n }}\n pageName=\"search\"\n >\n <Stack direction=\"column\" maxW=\"100vw\" pb={4} px={4} spacing={4}>\n <SearchBar\n bg=\"white\"\n onChange={searchAPI.onQueryChange}\n onSubmit={(e) => {\n searchAPI.setSort(undefined);\n searchAPI.onSubmit(e);\n }}\n value={searchAPI.query}\n />\n\n <Stack\n align={{ base: \"start\", lg: \"center\" }}\n direction={{ base: \"column-reverse\", lg: \"row\" }}\n justify={{ base: \"initial\", lg: \"space-between\" }}\n spacing={4}\n >\n <SearchDetails\n count={results.length}\n filtered={!!query}\n limit={limit}\n offset={offset}\n query={query}\n />\n\n <Box display={{ base: \"none\", md: \"initial\" }}>\n <SortedBy />\n </Box>\n\n <Box display={{ md: \"none\" }}>\n <SortAndFilterDrawer />\n </Box>\n </Stack>\n\n <PackageList items={page} />\n\n <Box w=\"full\">\n <PageControls\n getPageUrl={getUrl}\n offset={offset}\n pageLimit={pageLimit}\n />\n </Box>\n </Stack>\n </Page>\n );\n};\n","import { Grid } from \"@chakra-ui/react\";\nimport { FunctionComponent } from \"react\";\nimport { Page } from \"../../components/Page\";\nimport { FilterPanel } from \"./FilterPanel\";\nimport { SearchResults } from \"./SearchResults\";\nimport { SearchStateProvider } from \"./SearchState\";\nimport testIds from \"./testIds\";\n\nexport const SearchRedesign: FunctionComponent = () => {\n return (\n <SearchStateProvider>\n <Page\n meta={{\n title: \"Search - Construct Hub\",\n description:\n \"Search Construct Libraries for AWS CDK, CDK8s, and CDKtf\",\n }}\n pageName=\"search\"\n >\n <Grid\n data-testid={testIds.page}\n gap={4}\n h=\"full\"\n maxW=\"100%\"\n px={{ base: 0, md: 6 }}\n py={6}\n templateColumns={{ base: \"1fr\", md: \"auto 1fr\" }}\n templateRows=\"1fr\"\n >\n {/* Filter Panel Desktop */}\n <FilterPanel />\n\n {/* Results, Info, and Controls */}\n <SearchResults />\n </Grid>\n </Page>\n </SearchStateProvider>\n );\n};\n"],"sourceRoot":""}