diff --git a/.github/workflows/netlify-edge-functions-test.yml b/.github/workflows/netlify-edge-functions-test.yml new file mode 100644 index 000000000000..adc110d68ddb --- /dev/null +++ b/.github/workflows/netlify-edge-functions-test.yml @@ -0,0 +1,21 @@ +name: Run tests for netlify edge-functions + +on: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + +jobs: + netlify-tests: + strategy: + matrix: + deno-version: [1.46.0] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Deno + uses: denoland/setup-deno@3a041055d2e2068f6e2c59904ee0ec2dfa9d9665 + with: + deno-version: ${{ matrix.deno-version }} + - name: Test with Deno + run: deno test --allow-env --trace-ops netlify/**/*.test.ts + diff --git a/.gitignore b/.gitignore index 210beb93f6a7..0a69d4de26c5 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ cypress/videos *storybook.log /storybook-static/ coverage +deno.lock diff --git a/CODEOWNERS b/CODEOWNERS index e33f9f4e706b..ac1c2868806f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -15,4 +15,4 @@ markdown/community/*.md @thulieblack @quetzalliwrites README.md @quetzalliwrites @derberg @akshatnema @magicmatatjahu @mayaleeeee @asyncapi-bot-eve #docTriagers: TRohit20 BhaswatiRoy VaishnaviNandakumar J0SAL -#codeTriagers: sambhavgupta0705 +#codeTriagers: sambhavgupta0705 devilkiller-ag diff --git a/assets/docs/fragments/bindings-overview.md b/assets/docs/fragments/bindings-overview.md new file mode 100644 index 000000000000..5f92b0ca3800 --- /dev/null +++ b/assets/docs/fragments/bindings-overview.md @@ -0,0 +1 @@ +Bindings in AsyncAPI provide a way to add protocol-specific information to the AsyncAPI documentation. They can be added to different document parts, such as servers, channels, or messages; they specify standard details specific to a particular protocol. The purpose of bindings is to enhance the API's understanding and usage by providing additional context and configuration options for different protocols. diff --git a/components/CaseStudyCard.tsx b/components/CaseStudyCard.tsx index 1642b8244506..241e9b5aa84b 100644 --- a/components/CaseStudyCard.tsx +++ b/components/CaseStudyCard.tsx @@ -19,7 +19,7 @@ export default function CaseStudyCard({ studies = [] }: ICaseStudyCardProps) { return (
{studies.map((study, index) => ( - +
(false); - const [showMoreDescription, setShowMoreDescription] = useState(false); + const [isTruncated, setIsTruncated] = useState(false); const [readMore, setReadMore] = useState(false); const descriptionRef = useRef(null); // Decide whether to show full description or not in the card based on the number of lines occupied by the description. useEffect(() => { - const divHeight = descriptionRef.current?.offsetHeight || 0; - const numberOfLines = divHeight / 20; - - if (numberOfLines > 3) { - setShowMoreDescription(true); - } else { - setShowMoreDescription(false); + if (descriptionRef.current) { + setIsTruncated(descriptionRef.current?.scrollHeight! > descriptionRef.current?.clientHeight!); } - }, []); + }, [descriptionRef.current]); let onGit = false; @@ -91,17 +85,19 @@ export default function ToolsCard({ toolData }: ToolsCardProp) {
setTimeout(() => { - if (showMoreDescription) setShowDescription(true); + if (isTruncated) setShowDescription(true); }, 500) } > - +
+ {toolData.description} +
+ {showDescription && (
(false); // used to handle the preloader on the page const filterRef = useRef(); // used to provide ref to the Filter menu and outside click close feature const categoryRef = useRef(); // used to provide ref to the Category menu and outside click close feature const [openFilter, setOpenFilter] = useState(false); @@ -31,7 +27,6 @@ export default function ToolsDashboard() { // filter parameters extracted from the context const { isPaid, isAsyncAPIOwner, languages, technologies, categories } = useContext(ToolFilterContext); const [searchName, setSearchName] = useState(''); // state variable used to get the search name - const [toolsList, setToolsList] = useState({}); // state variable used to set the list of tools according to the filters applied const [checkToolsList, setCheckToolsList] = useState(true); // state variable used to check whether any tool is available according to the needs of the user. // useEffect function to enable the close Modal feature when clicked outside of the modal @@ -49,14 +44,6 @@ export default function ToolsDashboard() { }; }); - // sets the preloader on the page for 1 second - useEffect(() => { - setLoading(true); - setTimeout(() => { - setLoading(false); - }, 1000); - }, []); - // useEffect function to enable the close Category dropdown Modal feature when clicked outside of the modal useEffect(() => { const checkIfClickOutside = (event: MouseEvent) => { @@ -72,8 +59,8 @@ export default function ToolsDashboard() { }; }); - // Function to update the list of tools according to the current filters applied - const updateToolsList = () => { + // useMemo function to filter the tools according to the filters applied by the user + const toolsList = useMemo(() => { let tempToolsList: ToolsListData = {}; // Tools data list is first filtered according to the category filter if applied by the user. @@ -150,18 +137,36 @@ export default function ToolsDashboard() { } }); - setToolsList(tempToolsList); - }; + Object.keys(tempToolsList).map((category) => { + tempToolsList[category].elementRef = createRef(); + + return tempToolsList; + }); + + return tempToolsList; + }, [isPaid, isAsyncAPIOwner, languages, technologies, categories, searchName]); + + // useEffect to scroll to the opened category when url has category as element id + useEffect(() => { + const { hash } = window.location; + + if (hash) { + const elementID = decodeURIComponent(hash.slice(1)); + const element = toolsList[elementID]?.elementRef!; + if (element.current) { + document.documentElement.style.scrollPaddingTop = '6rem'; + element.current.scrollIntoView({ behavior: 'smooth' }); + document.documentElement.style.scrollPaddingTop = '0'; + } + } + }, []); + // Function to update the list of tools according to the current filters applied const clearFilters = () => { setOpenFilter(false); router.push('/tools', undefined, { shallow: true }); }; - useEffect(() => { - updateToolsList(); - }, [isPaid, isAsyncAPIOwner, languages, technologies, categories, searchName]); - const isFiltered = Boolean( isPaid !== 'all' || isAsyncAPIOwner || languages.length || technologies.length || categories.length ); @@ -226,20 +231,16 @@ export default function ToolsDashboard() { Clear Filters
)} - {loading ? ( - } pulsating /> - ) : ( -
- {checkToolsList ? ( - - ) : ( -
- not found -
Sorry, we don't have tools according to your needs.
-
- )} -
- )} +
+ {checkToolsList ? ( + + ) : ( +
+ not found +
Sorry, we don't have tools according to your needs.
+
+ )} +
); diff --git a/components/tools/ToolsList.tsx b/components/tools/ToolsList.tsx index 9e41e58caeaa..b6e6eeeafe51 100644 --- a/components/tools/ToolsList.tsx +++ b/components/tools/ToolsList.tsx @@ -22,7 +22,7 @@ export default function ToolsList({ toolsListData }: ToolsListProp) { {Object.keys(toolsListData).map((categoryName, index) => { if (toolsListData[categoryName].toolsList.length > 0) { return ( -
+
{categoryName} diff --git a/config/MAINTAINERS.json b/config/MAINTAINERS.json index 1d9a5cab3e3d..cdcde198a1f2 100644 --- a/config/MAINTAINERS.json +++ b/config/MAINTAINERS.json @@ -276,8 +276,7 @@ "template-for-generator-templates", "community", "diff", - "chatbot", - "infra" + "chatbot" ], "githubID": 6995927 }, @@ -447,8 +446,7 @@ "go-watermill-template", "template-for-go-projects", "parser-api", - "server-api", - "infra" + "server-api" ], "githubID": 1083296 }, @@ -972,5 +970,14 @@ "kotlin-asyncapi" ], "githubID": 39913716 + }, + { + "name": "Jonas S\u00fcskind", + "github": "sueskind", + "isTscMember": false, + "repos": [ + "kotlin-asyncapi" + ], + "githubID": 52210599 } ] \ No newline at end of file diff --git a/config/all-tags.json b/config/all-tags.json index bcbe78efc37c..9f22bcd87c86 100644 --- a/config/all-tags.json +++ b/config/all-tags.json @@ -1 +1 @@ -{"languages":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"},{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"},{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"},{"name":"HTML","color":"bg-[#E2A291]","borderColor":"border-[#E44D26]"},{"name":"C/C++","color":"bg-[#93CDEF]","borderColor":"border-[#0080CC]"},{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"},{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"},{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"},{"name":"Kotlin","color":"bg-[#B1ACDF]","borderColor":"border-[#756BD9]"},{"name":"Scala","color":"bg-[#FFA299]","borderColor":"border-[#DF301F]"},{"name":"Markdown","color":"bg-[#BABEBF]","borderColor":"border-[#445B64]"},{"name":"YAML","color":"bg-[#FFB764]","borderColor":"border-[#F1901F]"},{"name":"R","color":"bg-[#84B5ED]","borderColor":"border-[#246BBE]"},{"name":"Ruby","color":"bg-[#FF8289]","borderColor":"border-[#FF000F]"},{"name":"Rust","color":"bg-[#FFB8AA]","borderColor":"border-[#E43716]"},{"name":"Shell","color":"bg-[#87D4FF]","borderColor":"border-[#389ED7]"},{"name":"Groovy","color":"bg-[#B6D5E5]","borderColor":"border-[#609DBC]"}],"technologies":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Hermes","color":"bg-[#8AEEBD]","borderColor":"border-[#2AB672]"},{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"},{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"AWS","color":"bg-[#FF9F59]","borderColor":"border-[#EF6703]"},{"name":"Docker","color":"bg-[#B8E0FF]","borderColor":"border-[#2596ED]"},{"name":"Node-RED","color":"bg-[#FF7474]","borderColor":"border-[#8F0101]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Saas","color":"bg-[#6AB8EC]","borderColor":"border-[#2275AD]"},{"name":"Kubernetes-native","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Scala","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Azure","color":"bg-[#4B93FF]","borderColor":"border-[#015ADF]"},{"name":"Jenkins","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Flask","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Nest Js","color":"bg-[#E1224E]","borderColor":"border-[#B9012b]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Socket.IO","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Kotlin","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Gradle","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Groovy","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Markdown","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Shell","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"WebComponents","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Babel","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Storybook","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"AsyncAPI Generator","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"VSCode","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"SmartPaste","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JetBrains","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"IntelliJ IDEA","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Java","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"HTML","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}]} \ No newline at end of file +{"languages":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"},{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"},{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"},{"name":"HTML","color":"bg-[#E2A291]","borderColor":"border-[#E44D26]"},{"name":"C/C++","color":"bg-[#93CDEF]","borderColor":"border-[#0080CC]"},{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"},{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"},{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"},{"name":"Kotlin","color":"bg-[#B1ACDF]","borderColor":"border-[#756BD9]"},{"name":"Scala","color":"bg-[#FFA299]","borderColor":"border-[#DF301F]"},{"name":"Markdown","color":"bg-[#BABEBF]","borderColor":"border-[#445B64]"},{"name":"YAML","color":"bg-[#FFB764]","borderColor":"border-[#F1901F]"},{"name":"R","color":"bg-[#84B5ED]","borderColor":"border-[#246BBE]"},{"name":"Ruby","color":"bg-[#FF8289]","borderColor":"border-[#FF000F]"},{"name":"Rust","color":"bg-[#FFB8AA]","borderColor":"border-[#E43716]"},{"name":"Shell","color":"bg-[#87D4FF]","borderColor":"border-[#389ED7]"},{"name":"Groovy","color":"bg-[#B6D5E5]","borderColor":"border-[#609DBC]"}],"technologies":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Hermes","color":"bg-[#8AEEBD]","borderColor":"border-[#2AB672]"},{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"},{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"AWS","color":"bg-[#FF9F59]","borderColor":"border-[#EF6703]"},{"name":"Docker","color":"bg-[#B8E0FF]","borderColor":"border-[#2596ED]"},{"name":"Node-RED","color":"bg-[#FF7474]","borderColor":"border-[#8F0101]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Saas","color":"bg-[#6AB8EC]","borderColor":"border-[#2275AD]"},{"name":"Kubernetes-native","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Scala","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Azure","color":"bg-[#4B93FF]","borderColor":"border-[#015ADF]"},{"name":"Jenkins","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Flask","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Nest Js","color":"bg-[#E1224E]","borderColor":"border-[#B9012b]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Socket.IO","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Kotlin","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Gradle","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Groovy","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Markdown","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Shell","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"WebComponents","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Babel","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Storybook","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"AsyncAPI Generator","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JetBrains","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"IntelliJ IDEA","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"VSCode","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"SmartPaste","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Java","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"HTML","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}]} \ No newline at end of file diff --git a/config/tools-automated.json b/config/tools-automated.json index 94ea5b30fbe6..504b55f18f86 100644 --- a/config/tools-automated.json +++ b/config/tools-automated.json @@ -91,44 +91,44 @@ } }, { - "title": "Zod Sockets", - "description": "Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.", + "title": "SIO-AsyncAPI", + "description": "This is code-first approach to generate AsyncAPI specification from Socket.IO server.", "links": { - "websiteUrl": "https://www.npmjs.com/package/zod-sockets", - "repoUrl": "https://github.com/RobinTail/zod-sockets" + "websiteUrl": "https://github.com/daler-rahimov/sio-asyncapi", + "docsUrl": "https://github.com/daler-rahimov/sio-asyncapi", + "repoUrl": "https://github.com/daler-rahimov/sio-asyncapi" }, "filters": { - "language": "TypeScript", + "language": "Python", "technology": [ - "Node.js", - "TypeScript" + "Socket.IO", + "Flask" ], "categories": [ "code-first", - "dsl", - "framework" + "api" ], "hasCommercial": false, "isAsyncAPIOwner": false } }, { - "title": "SIO-AsyncAPI", - "description": "This is code-first approach to generate AsyncAPI specification from Socket.IO server.", + "title": "Zod Sockets", + "description": "Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.", "links": { - "websiteUrl": "https://github.com/daler-rahimov/sio-asyncapi", - "docsUrl": "https://github.com/daler-rahimov/sio-asyncapi", - "repoUrl": "https://github.com/daler-rahimov/sio-asyncapi" + "websiteUrl": "https://www.npmjs.com/package/zod-sockets", + "repoUrl": "https://github.com/RobinTail/zod-sockets" }, "filters": { - "language": "Python", + "language": "TypeScript", "technology": [ - "Socket.IO", - "Flask" + "Node.js", + "TypeScript" ], "categories": [ "code-first", - "api" + "dsl", + "framework" ], "hasCommercial": false, "isAsyncAPIOwner": false @@ -289,28 +289,6 @@ "DSL": { "description": "Writing YAML by hand is no fun, and maybe you don't want a GUI, so use a Domain Specific Language to write AsyncAPI in your language of choice.", "toolsList": [ - { - "title": "Zod Sockets", - "description": "Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.", - "links": { - "websiteUrl": "https://www.npmjs.com/package/zod-sockets", - "repoUrl": "https://github.com/RobinTail/zod-sockets" - }, - "filters": { - "language": "TypeScript", - "technology": [ - "Node.js", - "TypeScript" - ], - "categories": [ - "code-first", - "dsl", - "framework" - ], - "hasCommercial": false, - "isAsyncAPIOwner": false - } - }, { "title": "ZenWave SDK", "description": "DDD and API-First for Event-Driven Microservices", @@ -336,6 +314,28 @@ "hasCommercial": false, "isAsyncAPIOwner": false } + }, + { + "title": "Zod Sockets", + "description": "Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.", + "links": { + "websiteUrl": "https://www.npmjs.com/package/zod-sockets", + "repoUrl": "https://github.com/RobinTail/zod-sockets" + }, + "filters": { + "language": "TypeScript", + "technology": [ + "Node.js", + "TypeScript" + ], + "categories": [ + "code-first", + "dsl", + "framework" + ], + "hasCommercial": false, + "isAsyncAPIOwner": false + } } ] }, @@ -640,15 +640,18 @@ "description": "The following is a list of extensions for different IDEs like VSCode, IntelliJ IDEA and others", "toolsList": [ { - "title": "asyncapi-preview", - "description": "VSCode extension that enables you to:\n - Preview documentation generated using you AsyncAPI document. It uses AsyncAPI React component under the hood,\n - Create AsyncAPI documents faster using SmartPaste functionality\n", + "title": "jAsyncAPI - IDEA plugin", + "description": "Idea plugin for the java-asyncapi - Helps to edit and validate AsyncAPI schemas.", "links": { - "repoUrl": "https://github.com/asyncapi/vs-asyncapi-preview" + "websiteUrl": "https://plugins.jetbrains.com/plugin/15673-asyncapi", + "docsUrl": "https://github.com/asyncapi/jasyncapi-idea-plugin#usage", + "repoUrl": "https://github.com/asyncapi/jasyncapi-idea-plugin" }, "filters": { + "language": "Kotlin", "technology": [ - "VSCode", - "SmartPaste" + "JetBrains", + "IntelliJ IDEA" ], "categories": [ "ide-extension" @@ -658,18 +661,15 @@ } }, { - "title": "jAsyncAPI - IDEA plugin", - "description": "Idea plugin for the java-asyncapi - Helps to edit and validate AsyncAPI schemas.", + "title": "asyncapi-preview", + "description": "VSCode extension that enables you to:\n - Preview documentation generated using you AsyncAPI document. It uses AsyncAPI React component under the hood,\n - Create AsyncAPI documents faster using SmartPaste functionality\n", "links": { - "websiteUrl": "https://plugins.jetbrains.com/plugin/15673-asyncapi", - "docsUrl": "https://github.com/asyncapi/jasyncapi-idea-plugin#usage", - "repoUrl": "https://github.com/asyncapi/jasyncapi-idea-plugin" + "repoUrl": "https://github.com/asyncapi/vs-asyncapi-preview" }, "filters": { - "language": "Kotlin", "technology": [ - "JetBrains", - "IntelliJ IDEA" + "VSCode", + "SmartPaste" ], "categories": [ "ide-extension" @@ -701,6 +701,24 @@ "AsyncAPI Generator Templates": { "description": "The following is a list of templates compatible with AsyncAPI Generator. You can use them to generate apps, clients or documentation from your AsyncAPI documents.", "toolsList": [ + { + "title": "Node.js Websockets Template", + "description": "Node.js WebSockets template for the AsyncAPI Generator. It showcases how from a single AsyncAPI document you can generate a server and a client at the same time.", + "links": { + "repoUrl": "https://github.com/asyncapi/nodejs-ws-template" + }, + "filters": { + "language": "javascript", + "technology": [ + "Node.js" + ], + "categories": [ + "generator-template" + ], + "hasCommercial": false, + "isAsyncAPIOwner": true + } + }, { "title": "Java Template", "description": "Java template for the AsyncAPI Generator", @@ -722,15 +740,18 @@ } }, { - "title": "Node.js Websockets Template", - "description": "Node.js WebSockets template for the AsyncAPI Generator. It showcases how from a single AsyncAPI document you can generate a server and a client at the same time.", + "title": "Java Spring Cloud Stream Template", + "description": "Java Spring Cloud Stream template for the AsyncAPI Generator", "links": { - "repoUrl": "https://github.com/asyncapi/nodejs-ws-template" + "repoUrl": "https://github.com/asyncapi/java-spring-cloud-stream-template" }, "filters": { - "language": "javascript", + "language": [ + "javascript" + ], "technology": [ - "Node.js" + "Spring Cloud Streams", + "Maven" ], "categories": [ "generator-template" @@ -775,27 +796,6 @@ "isAsyncAPIOwner": true } }, - { - "title": "Java Spring Cloud Stream Template", - "description": "Java Spring Cloud Stream template for the AsyncAPI Generator", - "links": { - "repoUrl": "https://github.com/asyncapi/java-spring-cloud-stream-template" - }, - "filters": { - "language": [ - "javascript" - ], - "technology": [ - "Spring Cloud Streams", - "Maven" - ], - "categories": [ - "generator-template" - ], - "hasCommercial": false, - "isAsyncAPIOwner": true - } - }, { "title": "Java Spring Template", "description": "Java Spring template for the AsyncAPI Generator", diff --git a/jest.config.js b/jest.config.js index 496a9fddf929..25c7865434ed 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,5 +1,7 @@ module.exports = { - verbose: true, // display individual test results with the test suite hierarchy - collectCoverage: true, // collect test coverage information\ - collectCoverageFrom: ['scripts/**/*.js'] + verbose: true, + collectCoverage: true, + collectCoverageFrom: ['scripts/**/*.js'], + // To disallow netlify edge function tests from running + testMatch: ['**/tests/**/*.test.*', '!**/netlify/**/*.test.*'], }; diff --git a/markdown/blog/2022-summary.md b/markdown/blog/2022-summary.md index 2cd597418448..408e4b33a5df 100644 --- a/markdown/blog/2022-summary.md +++ b/markdown/blog/2022-summary.md @@ -11,7 +11,6 @@ authors: link: https://twitter.com/derberq byline: AsyncAPI Maintainer and Dev Comm Keeper excerpt: 'tl;dr We do not see any negative trends indicating that the interest in the project got stale and that the community is not growing anymore.' -featured: true --- It is a good practice to sometimes stop and turn back. Sometimes you need to see what you left behind, what successes made you go that far, and what things you missed and never had time to enjoy or explore. The more often you do it, the better your decisions may be in the future. It is essential to do it at least once a year in open source. diff --git a/markdown/blog/2023-mentorship-summary.md b/markdown/blog/2023-mentorship-summary.md index fa13cb92afb0..b594ff5b4bbc 100644 --- a/markdown/blog/2023-mentorship-summary.md +++ b/markdown/blog/2023-mentorship-summary.md @@ -11,7 +11,6 @@ authors: photo: /img/avatars/ace.webp link: https://twitter.com/_acebuild byline: AsyncAPI Preacher -featured: true --- diff --git a/markdown/blog/2023-summary.md b/markdown/blog/2023-summary.md index dd052e2577dd..78bce07df1e5 100644 --- a/markdown/blog/2023-summary.md +++ b/markdown/blog/2023-summary.md @@ -11,7 +11,6 @@ authors: link: https://www.linkedin.com/in/v-thulisile-sibanda/ byline: AsyncAPI Community Manager excerpt: '2023 Year in Review' -featured: true --- It's almost unbelievable that we are in 2024. And if you are reading this, Happy New Year to you and your loved ones. Continuing the tradition, we look at how the community has grown over the last 365 days and look forward to our next phase. diff --git a/markdown/blog/2024-Q1-docs-report.md b/markdown/blog/2024-Q1-docs-report.md index dcf9ead7c48c..3f5950eeedae 100644 --- a/markdown/blog/2024-Q1-docs-report.md +++ b/markdown/blog/2024-Q1-docs-report.md @@ -12,7 +12,6 @@ authors: link: https://www.linkedin.com/in/alejandra-quetzalli/ byline: During Q1 2024, AsyncAPI docs had a total of 26,923 sessions and 8,128 unique users. excerpt: During Q1 2024, AsyncAPI docs had a total of 26,923 sessions and 8,128 unique users. -featured: true --- # AsyncAPI Documentation Report - Q1 2024 diff --git a/markdown/blog/a_straight_guide_to_apis_and_architecture_concepts.md b/markdown/blog/a_straight_guide_to_apis_and_architecture_concepts.md index 1f2c4fe7f874..34d9b700c2f9 100644 --- a/markdown/blog/a_straight_guide_to_apis_and_architecture_concepts.md +++ b/markdown/blog/a_straight_guide_to_apis_and_architecture_concepts.md @@ -12,7 +12,6 @@ authors: photo: /img/avatars/barbano.webp link: https://www.linkedin.com/in/barbano-gonzalez-moreno excerpt: Basic concepts about APIs and architectures for beginners and non-developers. -featured: true --- It has not been such a long journey into the technology realm for me. Then I started to work at AsyncAPI, and suddenly, I needed to understand a complex world. New terms, code, and ways of seeing things were waiting for me. Coming from other fields of knowledge, the challenge was huge. How to begin? How to have a clue? diff --git a/markdown/blog/asyncapi-ambassador-program.md b/markdown/blog/asyncapi-ambassador-program.md index 35562aa67f04..b4c89987814b 100644 --- a/markdown/blog/asyncapi-ambassador-program.md +++ b/markdown/blog/asyncapi-ambassador-program.md @@ -10,7 +10,6 @@ authors: photo: /img/avatars/barbano.webp link: https://www.linkedin.com/in/barbano-gonzalez-moreno excerpt: Information about AsyncAPI Ambassador Program. -featured: true --- AsyncAPI and its community have grown exponentially during the last few months. As a feedback exercise, both the project and the community are getting stronger with one another. The community is the driving force that leads the initiative and the bigger it gets, the greater the consistency and potential it has. It’s amazing to see a vast number of people who invest their time in disseminating and promoting the initiative through talks, articles, workshops, and program direction... diff --git a/markdown/blog/asyncapi-say-hi-to-triggermesh.md b/markdown/blog/asyncapi-say-hi-to-triggermesh.md index 68bbfc9c1017..6f2709e1e46d 100644 --- a/markdown/blog/asyncapi-say-hi-to-triggermesh.md +++ b/markdown/blog/asyncapi-say-hi-to-triggermesh.md @@ -10,7 +10,6 @@ authors: link: https://twitter.com/j_michaux byline: Product at TriggerMesh excerpt: TriggerMesh makes it easy to reliably pipe events from any source to any destination. Let's use it to read from AsyncAPI channels, and see how to autogenerate the TriggerMesh config. -featured: true --- This tutorial demonstrates how to use AsyncAPI with TriggerMesh. It shows how the two play nicely together because TriggerMesh can easily ingest, transform, filter, and route events from channels defined in an AsyncAPI definition. This is one of many possible ways to use the two technologies together. This post assumes you have basic knowledge of AsyncAPI already, but are potentially new to TriggerMesh. diff --git a/markdown/blog/asyncapi-website-migration.md b/markdown/blog/asyncapi-website-migration.md index 5d159e9aef62..2229d79765bc 100644 --- a/markdown/blog/asyncapi-website-migration.md +++ b/markdown/blog/asyncapi-website-migration.md @@ -13,7 +13,6 @@ authors: link: https://ashmit.dev/ byline: Modelina Website Maintainer excerpt: 'Migration journey of the AsyncAPI Website, features introduced, and future plans.' -featured: true --- We're thrilled to announce the successful migration of the AsyncAPI website from JavaScript and Next.js v12 to TypeScript and Next.js v14! This exciting upgrade unlocks a new chapter for the website, paving the way for improved scalability, streamlined feature implementation, and the powerful capabilities of Next.js. As a bonus, this migration also enabled a well-documented codebase and streamlined our testing process by reducing the reliance on Cypress tests. In this blog post, we'll delve into the exciting journey behind the migration and share what's new on the website. I'll share insights into our team's efforts, the research and planning involved, the challenges we tackled, the valuable lessons learned, and what exciting plans lie ahead for the AsyncAPI website. diff --git a/markdown/blog/beyond-boundaries.md b/markdown/blog/beyond-boundaries.md index 590a28271f63..155b85db0a85 100644 --- a/markdown/blog/beyond-boundaries.md +++ b/markdown/blog/beyond-boundaries.md @@ -12,8 +12,7 @@ authors: - name: Azeez Elegbede photo: /img/avatars/ace.webp link: https://twitter.com/_acebuild - byline: AsyncAPI Preacher -featured: true + byline: AsyncAPI Preacher --- In 2022 we piloted our innovative mentorship program that focuses on open-source software(OSS). We envisioned a platform where aspiring developers could learn, grow, and contribute to exciting projects while receiving guidance from experienced mentors. diff --git a/markdown/blog/conference-2022.md b/markdown/blog/conference-2022.md index 751094544f88..b6033ba376c2 100644 --- a/markdown/blog/conference-2022.md +++ b/markdown/blog/conference-2022.md @@ -5,7 +5,6 @@ type: Conference tags: - Conference cover: /img/posts/conference-2022.webp -featured: true authors: - name: Azeez Elegbede photo: /img/avatars/ace.webp diff --git a/markdown/blog/conference-2023.md b/markdown/blog/conference-2023.md index fcf01bc626a6..c3a7e352e00b 100644 --- a/markdown/blog/conference-2023.md +++ b/markdown/blog/conference-2023.md @@ -11,7 +11,6 @@ authors: link: https://www.linkedin.com/in/v-thulisile-sibanda/ byline: AsyncAPI Community Manager excerpt: In 2023, we hosted our very first in-person conference edition. Find out how it all went down! -featured: true --- For three consecutive years, we have hosted online conferences, and in 2023, we decided to take it up a notch and move to in-person events. diff --git a/markdown/blog/gravitee-annoucement.md b/markdown/blog/gravitee-annoucement.md index 8fb4f4e30cd5..252ee3e2a46f 100644 --- a/markdown/blog/gravitee-annoucement.md +++ b/markdown/blog/gravitee-annoucement.md @@ -11,7 +11,6 @@ authors: link: https://www.linkedin.com/in/atinuke-oluwabamikemi-kayode-5b838b1b7/ byline: AsyncAPI Community Marketing Specialist excerpt: 'Gravitee Sponsorship Announcement' -featured: true --- ## Gravitee Sponsorship Announcement diff --git a/markdown/blog/hacktoberfest-2022.md b/markdown/blog/hacktoberfest-2022.md index 4832735976cc..6dc75e08357a 100644 --- a/markdown/blog/hacktoberfest-2022.md +++ b/markdown/blog/hacktoberfest-2022.md @@ -5,7 +5,6 @@ type: Community tags: - Hacktoberfest cover: /img/posts/asyncapiXhacktoberfest.webp -featured: true authors: - name: Azeez Elegbede photo: /img/avatars/ace.webp diff --git a/markdown/blog/helsinki-and-community.md b/markdown/blog/helsinki-and-community.md new file mode 100644 index 000000000000..ffb47a8f82a7 --- /dev/null +++ b/markdown/blog/helsinki-and-community.md @@ -0,0 +1,88 @@ +--- +title: "AsyncAPI Conference Helsinki and the API Specs and Standards Concept" +date: 2024-09-13T06:00:00+01:00 +type: Communication +tags: + - Conference +cover: /img/posts/helsinki-and-community/booth-top.webp +authors: + - name: Lukasz Gornicki + photo: /img/avatars/lpgornicki.webp + link: https://twitter.com/derberq + byline: AsyncAPI Executive Director +excerpt: 'Conferences are great. They bring communities together and give people a platform to share their experiences. But is that enough?' +featured: true +--- + +## How It All Started + +After three years of hosting online conferences (2020-2022), the AsyncAPI community felt it was time for something different— an in-person event. We wanted to meet people face-to-face, to confirm that behind the virtual interactions were real humans, the ones you could have meaningful conversations with, not bots! + +In 2023, we organized multiple events under the brand `AsyncAPI Conf on Tour`. One of them took place at [APIDays Paris](https://www.apidays.global/paris2023/), made possible by the amazing folks behind [APIDays](https://www.apidays.global/), who share our belief in the future of strong API specifications and standards. + +It was a fantastic opportunity, but we had one major concern—how do we find our community members in an event with thousands of attendees? How do we have meaningful conversations? And how do we engage with people who don’t know about AsyncAPI yet? +As you probably know, conference talks end, and people scatter. It’s easy to lose them in the crowd. + +One of the best places to meet people at conferences is at the sponsor booths. But as an open-source, community-driven project, we don’t have the budget for that kind of setup. + +Once again, [APIDays](https://www.apidays.global/) came to the rescue and offered us a booth. + +We decided to take it one step further—not just a booth for AsyncAPI, but a shared space for other open-source communities. At Paris 2023, we organized the first `API Specs & Standards` booth, bringing together AsyncAPI, OpenAPI, and JSON Schema experts. We created a vendor-neutral, safe space for knowledge exchange, where experts from different companies shared their expertise without pushing for their products. + +## AsyncAPI Conf on Tour at APIDays Helsinki 2024 + +Our next stop was [APIDays Helsinki 2024](https://www.apidays.global/helsinki_and_north/). + +Hugo kicked things off with a great introduction to the AsyncAPI spec and later wrapped up the track with an excellent session on testing event-driven architectures. + +
+ +Jonas followed with a detailed overview of the AsyncAPI tooling ecosystem, showcasing the various tools built around the specification to support developers working with AsyncAPI documents. + +
+ +I then presented an overview of AsyncAPI use cases, demonstrating how different companies use AsyncAPI in production, all based on real data we’ve gathered over the years. You can explore all of this in our [AsyncAPI case studies](/casestudies). + +
+ +The talks were engaging, and the questions that followed were great. Slides from the talks are [available for download](https://drive.google.com/drive/folders/1nY7dZF8WFXZ3r2rCWJDDoT2C_GMfQJMV). But the best, most technical, and insightful conversations happened at the `API Specs and Standards` booth. We teamed up with friends from the OpenAPI Initiative and had deep, meaningful discussions. + +
+ +## September 18-19 in London + +I won’t be attending the London event this year, but plenty of other folks will, especially at the `API Specs and Standards` booth. I hope you all have as much fun there as we did in Helsinki! + +
+ +If you haven’t grabbed your ticket yet, AsyncAPI community members can get free passes. Just [check out the agenda and reserve your spot](https://conference.asyncapi.com/venue/London). + +## December in Paris and the future of the Booth + +Looking ahead to December, we’ll have some free passes for the Paris event too. But honestly, the best experience is joining as a speaker. Not only do you get a free pass, but you also get to attend the speaker’s party the night before the event. Most importantly, it’s a unique opportunity to share your story with the wider [AsyncAPI](https://conference.asyncapi.com/venue/Paris) community. CfP is still open. + +Of course, we’ll have a booth again. This time, it won’t just be AsyncAPI and OpenAPI folks—our friends from JSON Schema will join too. + +Since it’s the fourth time we’ll be hosting this booth, I have a feeling it’s time to take things up a notch. We need to be more organized, include more community members, and maybe even secure some dedicated funding. A rebranding could be in order, too—perhaps renaming the booth to `Open API Standards`. We could also broaden the scope to include experts from the open-source tooling ecosystem that builds on top of these standards and operates under open governance. + +Enjoy! diff --git a/markdown/blog/new-asyncapi-tools-page.md b/markdown/blog/new-asyncapi-tools-page.md index 945d65a2da5c..3d6d499eeb6c 100644 --- a/markdown/blog/new-asyncapi-tools-page.md +++ b/markdown/blog/new-asyncapi-tools-page.md @@ -12,7 +12,6 @@ authors: link: https://twitter.com/AksNema byline: AsyncAPI Maintainer and Dev Akshat Nema excerpt: "Announcing our newly released AsyncAPI tools dashboard!" -featured: true --- We already know that the present list of tools used inside AsyncAPI is presented on [AsyncAPI Tools Overview](/docs/tools) and it is manually maintained inside the GitHub repository. All the tools are sorted according to the different categories in which they are used and maintained by the contributors. But we don't have a way to filter the tools according to our interest 🤔, like languages, technologies used in it, open-source tools, etc. Also, what if you want to add your tool to the list, what you will do 🤔? Do you have to create a PR? diff --git a/markdown/blog/release-notes-2.6.0.md b/markdown/blog/release-notes-2.6.0.md index d5afd8cc0893..73d494d16435 100644 --- a/markdown/blog/release-notes-2.6.0.md +++ b/markdown/blog/release-notes-2.6.0.md @@ -12,7 +12,6 @@ authors: link: https://twitter.com/acethecreator byline: Software Engineer & Open-Source Advocate excerpt: "The release of AsyncAPI 2.6 added an exciting feature which is the support for Apache Pulsar" -featured: true --- The new version of the AsyncAPI specification - 2.6.0 - is now available. diff --git a/markdown/blog/socketio-automatic-docs.md b/markdown/blog/socketio-automatic-docs.md index 0cdab23d6d35..df775f6d2248 100644 --- a/markdown/blog/socketio-automatic-docs.md +++ b/markdown/blog/socketio-automatic-docs.md @@ -1,7 +1,6 @@ --- title: Flask-SocketIO Automated Documentation and Validation date: 2023-03-02T06:00:00+01:00 -featured: true type: Engineering tags: ['Python','SocketIO','Flask-SocketIO'] cover: /img/posts/socketio-automatic-docs/cover.webp diff --git a/markdown/blog/the-new-era-approaches.md b/markdown/blog/the-new-era-approaches.md index 0f051ecb2ed1..e3818f80ade7 100644 --- a/markdown/blog/the-new-era-approaches.md +++ b/markdown/blog/the-new-era-approaches.md @@ -12,7 +12,6 @@ authors: photo: /img/avatars/jonaslagoni.webp link: https://www.linkedin.com/in/jonaslagoni/ excerpt: "An update around AsyncAPI 3.0, where we are, what is remaining, release schedule, and a first look at 3.0" -featured: true --- Back in [March 2022](https://www.asyncapi.com/blog/async-api-spec-3.0-release), you heard the first official words around AsyncAPI 3.0. Since then, a lot of people have been working diligently across many expertise to bring it to life. And with its current state, it's finally time to give an update on the progress. diff --git a/markdown/docs/concepts/asyncapi-document/adding-bindings.md b/markdown/docs/concepts/asyncapi-document/adding-bindings.md index ef5d75de346a..7380fc5c30a3 100644 --- a/markdown/docs/concepts/asyncapi-document/adding-bindings.md +++ b/markdown/docs/concepts/asyncapi-document/adding-bindings.md @@ -3,7 +3,9 @@ title: Adding bindings weight: 260 --- -Bindings in AsyncAPI provide a way to add protocol-specific information to the AsyncAPI documentation. They can be added to different document parts, such as servers, channels, or messages; they specify standard details specific to a particular protocol. The purpose of bindings is to enhance the API's understanding and usage by providing additional context and configuration options for different protocols. +import BindingsOverview from '../../../../assets/docs/fragments/bindings-overview.md' + + The following diagram highlights the sections where bindings can be implemented: diff --git a/markdown/docs/concepts/asyncapi-document/structure.md b/markdown/docs/concepts/asyncapi-document/structure.md index 6beb3d9b865a..9b3d9fb9be2e 100644 --- a/markdown/docs/concepts/asyncapi-document/structure.md +++ b/markdown/docs/concepts/asyncapi-document/structure.md @@ -351,7 +351,7 @@ operations: The `components` field allows for the definition of reusable structures or definitions applicable across various sections of your document. Items detailed within `components` only become part of the API when explicitly referenced by properties external to this field. Utilize it to avoid repetition and enhance the document's maintainability. -Key components of the `channels` field include: +Key components of the `components` field include: - `schemas`: An object to hold the reusable [Schema Object](/docs/reference/specification/latest#schemaObject). - `servers`: An object to hold the reusable [Server Objects](/docs/reference/specification/latest#serverObject). diff --git a/markdown/docs/reference/bindings/_section.md b/markdown/docs/reference/bindings/_section.md new file mode 100644 index 000000000000..1b810dd42e3d --- /dev/null +++ b/markdown/docs/reference/bindings/_section.md @@ -0,0 +1,4 @@ +--- +title: Bindings +weight: 15 +--- diff --git a/markdown/docs/reference/bindings/index.md b/markdown/docs/reference/bindings/index.md new file mode 100644 index 000000000000..314c533f0ae4 --- /dev/null +++ b/markdown/docs/reference/bindings/index.md @@ -0,0 +1,18 @@ +--- +title: Overview +weight: 15 +--- + +## Overview + +import BindingsOverview from '../../../../assets/docs/fragments/bindings-overview.md' + + + +## Usage in an AsyncAPI document + +To learn how to add bindings to your AsyncAPI document, read [Adding bindings](/docs/concepts/asyncapi-document/adding-bindings) concept document, or read the guide about using [Kafka bindings](/docs/tutorials/kafka/bindings-with-kafka). + +## Contributing to bindings + +Bindings are maintained by different community members that know and use given protocol and technology in production. If something can be improved, or some new binding is needed, open an issue in [bindings repository](https://github.com/asyncapi/bindings). diff --git a/markdown/docs/tools/cli/usage.md b/markdown/docs/tools/cli/usage.md index 7d40f79d64fe..c1dedde17575 100644 --- a/markdown/docs/tools/cli/usage.md +++ b/markdown/docs/tools/cli/usage.md @@ -27,7 +27,7 @@ $ npm install -g @asyncapi/cli $ asyncapi COMMAND running command... $ asyncapi (--version) -@asyncapi/cli/2.3.11 linux-x64 node-v18.20.4 +@asyncapi/cli/2.3.12 linux-x64 node-v18.20.4 $ asyncapi --help [COMMAND] USAGE $ asyncapi COMMAND @@ -99,7 +99,7 @@ EXAMPLES $ asyncapi bundle ./asyncapi.yaml -o final-asyncapi.yaml --base ../public-api/main.yaml --baseDir ./social-media/comments-service ``` -_See code: [src/commands/bundle.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/bundle.ts)_ +_See code: [src/commands/bundle.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/bundle.ts)_ ## `asyncapi config` @@ -113,7 +113,7 @@ DESCRIPTION CLI config settings ``` -_See code: [src/commands/config/index.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/index.ts)_ +_See code: [src/commands/config/index.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/index.ts)_ ## `asyncapi config analytics` @@ -133,7 +133,7 @@ DESCRIPTION Enable or disable analytics for metrics collection ``` -_See code: [src/commands/config/analytics.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/analytics.ts)_ +_See code: [src/commands/config/analytics.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/analytics.ts)_ ## `asyncapi config context` @@ -147,7 +147,7 @@ DESCRIPTION Manage short aliases for full paths to AsyncAPI documents ``` -_See code: [src/commands/config/context/index.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/context/index.ts)_ +_See code: [src/commands/config/context/index.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/context/index.ts)_ ## `asyncapi config context add CONTEXT-NAME SPEC-FILE-PATH` @@ -169,7 +169,7 @@ DESCRIPTION Add a context to the store ``` -_See code: [src/commands/config/context/add.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/context/add.ts)_ +_See code: [src/commands/config/context/add.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/context/add.ts)_ ## `asyncapi config context current` @@ -186,7 +186,7 @@ DESCRIPTION Shows the current context that is being used ``` -_See code: [src/commands/config/context/current.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/context/current.ts)_ +_See code: [src/commands/config/context/current.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/context/current.ts)_ ## `asyncapi config context edit CONTEXT-NAME NEW-SPEC-FILE-PATH` @@ -207,7 +207,7 @@ DESCRIPTION Edit a context in the store ``` -_See code: [src/commands/config/context/edit.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/context/edit.ts)_ +_See code: [src/commands/config/context/edit.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/context/edit.ts)_ ## `asyncapi config context init [CONTEXT-FILE-PATH]` @@ -230,7 +230,7 @@ DESCRIPTION Initialize context ``` -_See code: [src/commands/config/context/init.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/context/init.ts)_ +_See code: [src/commands/config/context/init.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/context/init.ts)_ ## `asyncapi config context list` @@ -247,7 +247,7 @@ DESCRIPTION List all the stored contexts in the store ``` -_See code: [src/commands/config/context/list.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/context/list.ts)_ +_See code: [src/commands/config/context/list.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/context/list.ts)_ ## `asyncapi config context remove CONTEXT-NAME` @@ -267,7 +267,7 @@ DESCRIPTION Delete a context from the store ``` -_See code: [src/commands/config/context/remove.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/context/remove.ts)_ +_See code: [src/commands/config/context/remove.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/context/remove.ts)_ ## `asyncapi config context use CONTEXT-NAME` @@ -287,7 +287,7 @@ DESCRIPTION Set a context as current ``` -_See code: [src/commands/config/context/use.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/context/use.ts)_ +_See code: [src/commands/config/context/use.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/context/use.ts)_ ## `asyncapi config versions` @@ -304,7 +304,7 @@ DESCRIPTION Show versions of AsyncAPI tools used ``` -_See code: [src/commands/config/versions.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/config/versions.ts)_ +_See code: [src/commands/config/versions.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/config/versions.ts)_ ## `asyncapi convert [SPEC-FILE]` @@ -326,7 +326,7 @@ DESCRIPTION Convert asyncapi documents older to newer versions ``` -_See code: [src/commands/convert.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/convert.ts)_ +_See code: [src/commands/convert.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/convert.ts)_ ## `asyncapi diff OLD NEW` @@ -366,7 +366,7 @@ DESCRIPTION Find diff between two asyncapi files ``` -_See code: [src/commands/diff.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/diff.ts)_ +_See code: [src/commands/diff.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/diff.ts)_ ## `asyncapi generate` @@ -380,7 +380,7 @@ DESCRIPTION Generate typed models or other things like clients, applications or docs using AsyncAPI Generator templates. ``` -_See code: [src/commands/generate/index.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/generate/index.ts)_ +_See code: [src/commands/generate/index.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/generate/index.ts)_ ## `asyncapi generate fromTemplate ASYNCAPI TEMPLATE` @@ -424,7 +424,7 @@ EXAMPLES $ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template --param version=1.0.0 singleFile=true --output ./docs --force-write ``` -_See code: [src/commands/generate/fromTemplate.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/generate/fromTemplate.ts)_ +_See code: [src/commands/generate/fromTemplate.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/generate/fromTemplate.ts)_ ## `asyncapi generate models LANGUAGE FILE` @@ -495,7 +495,7 @@ DESCRIPTION Generates typed models ``` -_See code: [src/commands/generate/models.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/generate/models.ts)_ +_See code: [src/commands/generate/models.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/generate/models.ts)_ ## `asyncapi new` @@ -553,7 +553,7 @@ EXAMPLES $ asyncapi new --file-name=my-asyncapi.yml --example=default-example.yml --no-tty - create a new file with a specific name, using one of the examples and without interactive mode ``` -_See code: [src/commands/new/index.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/new/index.ts)_ +_See code: [src/commands/new/index.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/new/index.ts)_ ## `asyncapi new file` @@ -611,7 +611,7 @@ EXAMPLES $ asyncapi new --file-name=my-asyncapi.yml --example=default-example.yml --no-tty - create a new file with a specific name, using one of the examples and without interactive mode ``` -_See code: [src/commands/new/file.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/new/file.ts)_ +_See code: [src/commands/new/file.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/new/file.ts)_ ## `asyncapi new glee` @@ -633,7 +633,7 @@ DESCRIPTION Creates a new Glee project ``` -_See code: [src/commands/new/glee.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/new/glee.ts)_ +_See code: [src/commands/new/glee.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/new/glee.ts)_ ## `asyncapi new template` @@ -657,7 +657,7 @@ DESCRIPTION Creates a new template ``` -_See code: [src/commands/new/template.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/new/template.ts)_ +_See code: [src/commands/new/template.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/new/template.ts)_ ## `asyncapi optimize [SPEC-FILE]` @@ -699,7 +699,7 @@ EXAMPLES $ asyncapi optimize ./asyncapi.yaml --ignore=schema ``` -_See code: [src/commands/optimize.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/optimize.ts)_ +_See code: [src/commands/optimize.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/optimize.ts)_ ## `asyncapi start` @@ -708,7 +708,7 @@ USAGE $ asyncapi start ``` -_See code: [src/commands/start/index.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/start/index.ts)_ +_See code: [src/commands/start/index.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/start/index.ts)_ ## `asyncapi start studio` @@ -727,7 +727,7 @@ DESCRIPTION starts a new local instance of Studio ``` -_See code: [src/commands/start/studio.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/start/studio.ts)_ +_See code: [src/commands/start/studio.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/start/studio.ts)_ ## `asyncapi validate [SPEC-FILE]` @@ -757,5 +757,5 @@ DESCRIPTION validate asyncapi file ``` -_See code: [src/commands/validate.ts](https://github.com/asyncapi/cli/blob/v2.3.11/src/commands/validate.ts)_ +_See code: [src/commands/validate.ts](https://github.com/asyncapi/cli/blob/v2.3.12/src/commands/validate.ts)_ diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 834565d2fe88..2f9a32934a25 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -1,4 +1,5 @@ -import type { Context } from "netlify:edge"; +// Changes to URL from 'netlify:edge' because we don't have package aliasing setup in our workflow. +import type { Context } from "https://edge-bootstrap.netlify.app/v1/index.ts"; const GITHUB_TOKEN = Deno.env.get("GITHUB_TOKEN_NR"); const NR_API_KEY = Deno.env.get("NR_API_KEY"); @@ -69,7 +70,8 @@ export default async (request: Request, context: Context) => { function buildRewrite(originalRequest: Request): (Request | null) { const extractResult = SchemasRelatedRequestRegex.exec(new URL(originalRequest.url).pathname); - if (extractResult === null) { + // No need to rewrite the request if it's not a legitimate request for a definition file + if (extractResult === null || extractResult.length < 2 || !extractResult[2]) { return null; } diff --git a/netlify/edge-functions/tests/serve-definitions.test.ts b/netlify/edge-functions/tests/serve-definitions.test.ts new file mode 100644 index 000000000000..ea9bbdf76215 --- /dev/null +++ b/netlify/edge-functions/tests/serve-definitions.test.ts @@ -0,0 +1,218 @@ +import serveDefinitions from "../serve-definitions.ts"; +import { Context } from "https://edge-bootstrap.netlify.app/v1/index.ts"; +import * as mf from "https://deno.land/x/mock_fetch@0.3.0/mod.ts"; +import { assertEquals } from "https://deno.land/std@0.208.0/assert/assert_equals.ts"; + +const metricURL = "https://metric-api.eu.newrelic.com/metric/v1"; + +const validRequests = [ + { + requestURL: "https://asyncapi.com/definitions/2.4.0/info.json", + responseURL: + "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/definitions/2.4.0/info.json", + }, + { + requestURL: "https://asyncapi.com/definitions/2.4.0.json", + responseURL: + "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas/2.4.0.json", + }, + { + requestURL: "https://asyncapi.com/schema-store/2.5.0/operation.json", + responseURL: + "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/definitions/2.5.0/operation.json", + }, + { + requestURL: "https://asyncapi.com/schema-store/2.5.0-without-$id.json", + responseURL: + "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas/2.5.0-without-$id.json", + }, +]; + +const invalidRequests = [ + { + requestURL: "https://asyncapi.com/definitions/asyncapi.yaml", + }, + { + requestURL: "https://asyncapi.com/schema-store/2.4.0.JSON", + }, + { + requestURL: "https://asyncapi.com/foobar", + }, + { + requestURL: "https://asyncapi.com/", + }, +]; + +const context = { + next: () => {}, + log: () => {}, +}; + +let metricCalls = 0; + +function setup() { + mf.install(); + + mf.mock("*", (req) => { + console.log(req.url); + + if (req.url === metricURL) { + metricCalls++; + } + + const body = { + url: req.url, + method: req.method, + headers: req.headers, + }; + + return new Response(JSON.stringify(body), { + status: 200, + headers: { + "Content-Type": "application/json", + }, + }); + }); +} + +Deno.test("serve-definitions test for validRequests", async () => { + metricCalls = 0; + + setup(); + + for (const entry of validRequests) { + console.log("Testing: " + entry.requestURL); + + const request = new Request(entry.requestURL, { method: "GET" }); + const response = await serveDefinitions(request, context as Context); + const body = await response.json(); + + assertEquals(response.status, 200); + assertEquals(response.headers.get("Content-Type"), "application/schema+json"); + assertEquals(body.url, entry.responseURL); + + console.log("\n"); + } + + assertEquals(metricCalls, validRequests.length); + + mf.uninstall(); +}); + +Deno.test("serve-definitions test for invalidRequests", async () => { + metricCalls = 0; + + setup(); + + for (const entry of invalidRequests) { + console.log("Testing: " + entry.requestURL); + const request = new Request(entry.requestURL, { method: "GET" }); + const response = await serveDefinitions(request, context as Context); + + assertEquals(response, undefined); + } + + // No metrics should be sent for invalid requests + assertEquals(metricCalls, 0); + + mf.uninstall(); +}); + +Deno.test("serve-definitions test for various response statuses", async () => { + const testCases = [ + { requestURL: "https://asyncapi.com/definitions/2.4.0/info.json", status: 200, mockParam: "GET@https://asyncapi.com/definitions/2.4.0/info.json" }, + { requestURL: "https://asyncapi.com/definitions/2.4.0/info.json", status: 304, mockParam: "GET@https://asyncapi.com/definitions/2.4.0/info.json" }, + { requestURL: "https://asyncapi.com/definitions/2.4.0/info.json", status: 404, mockParam: "GET@https://asyncapi.com/definitions/2.4.0/info.json" }, + { requestURL: "https://asyncapi.com/definitions/2.4.0/info.json", status: 500, mockParam: "GET@https://asyncapi.com/definitions/2.4.0/info.json" }, + ]; + + for (const { requestURL, status, mockParam } of testCases) { + console.log("Testing: " + requestURL); + + mf.install(); + + mf.mock("*", () => { + return new Response(status === 200 ? JSON.stringify({ url: requestURL }) : null, { + status, + }); + }); + + const request = new Request(requestURL, { method: "GET" }); + const response = await serveDefinitions(request, context as Context); + + if (status === 200) { + const body = response.body ? await response.json() : null; + assertEquals(response.status, status); + assertEquals(body?.url, requestURL); + } else { + assertEquals(response.status, status); + } + + if (status === 200 || status === 304) { + metricCalls++; + } + + + console.log("\n"); + mf.uninstall(); + } + + assertEquals(metricCalls, testCases.filter((testCase) => testCase.status === 200 || testCase.status === 304).length); +}); + +Deno.test("serve-definitions test for schema-unrelated requests", async () => { + setup(); + + const schemaUnrelatedRequests = [ + "https://asyncapi.com/definitions/asyncapi.yaml", + "https://asyncapi.com/schema-store/2.4.0.JSON", + "https://asyncapi.com/foobar", + "https://asyncapi.com/", + ]; + + for (const requestURL of schemaUnrelatedRequests) { + console.log("Testing: " + requestURL); + const request = new Request(requestURL, { method: "GET" }); + const response = await serveDefinitions(request, context as Context); + + assertEquals(response, undefined); + } + + mf.uninstall(); +}); + +Deno.test("serve-definitions test for schema-related non-JSON requests", async () => { + setup(); + metricCalls = 0; + + const schemaRelatedNonJsonRequests = [ + "https://asyncapi.com/schema-store/2.5.0-without-$id", + ]; + + for (const requestURL of schemaRelatedNonJsonRequests) { + const context = { + next: () => { + return new Response(JSON.stringify({ url: requestURL }), { + status: 200, + headers: { + "Content-Type": "application/json", + }, + }); + }, + log: () => {}, + } + + console.log("Testing: " + requestURL); + const request = new Request(requestURL, { method: "GET" }); + const response = await serveDefinitions(request, context as unknown as Context); + const body = response?.body ? await response.json() : null; + + assertEquals(response?.status, 200); + assertEquals(body.url, requestURL); + assertEquals(response.headers.get("Content-Type"), "application/json"); // Default content type for non-JSON requests + } + + mf.uninstall(); + + assertEquals(metricCalls, 0); +}); diff --git a/package-lock.json b/package-lock.json index 768c59507b2a..376d20951273 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,7 +47,7 @@ "md5": "^2.3.0", "mermaid": "9.3.0", "moment": "^2.30.1", - "next": "14.1.1", + "next": "14.2.12", "next-i18next": "^15.3.0", "next-language-detector": "^1.1.0", "next-mdx-remote": "^4.4.1", @@ -4826,9 +4826,9 @@ } }, "node_modules/@next/env": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1.tgz", - "integrity": "sha512-7CnQyD5G8shHxQIIg3c7/pSeYFeMhsNbpU/bmvH7ZnDql7mNRgg8O2JZrhrc/soFnfBnKP4/xXNiiSIPn2w8gA==" + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.12.tgz", + "integrity": "sha512-3fP29GIetdwVIfIRyLKM7KrvJaqepv+6pVodEbx0P5CaMLYBtx+7eEg8JYO5L9sveJO87z9eCReceZLi0hxO1Q==" }, "node_modules/@next/eslint-plugin-next": { "version": "14.1.0", @@ -4900,9 +4900,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1.tgz", - "integrity": "sha512-yDjSFKQKTIjyT7cFv+DqQfW5jsD+tVxXTckSe1KIouKk75t1qZmj/mV3wzdmFb0XHVGtyRjDMulfVG8uCKemOQ==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.12.tgz", + "integrity": "sha512-crHJ9UoinXeFbHYNok6VZqjKnd8rTd7K3Z2zpyzF1ch7vVNKmhjv/V7EHxep3ILoN8JB9AdRn/EtVVyG9AkCXw==", "cpu": [ "arm64" ], @@ -4915,9 +4915,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1.tgz", - "integrity": "sha512-KCQmBL0CmFmN8D64FHIZVD9I4ugQsDBBEJKiblXGgwn7wBCSe8N4Dx47sdzl4JAg39IkSN5NNrr8AniXLMb3aw==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.12.tgz", + "integrity": "sha512-JbEaGbWq18BuNBO+lCtKfxl563Uw9oy2TodnN2ioX00u7V1uzrsSUcg3Ep9ce+P0Z9es+JmsvL2/rLphz+Frcw==", "cpu": [ "x64" ], @@ -4930,9 +4930,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1.tgz", - "integrity": "sha512-YDQfbWyW0JMKhJf/T4eyFr4b3tceTorQ5w2n7I0mNVTFOvu6CGEzfwT3RSAQGTi/FFMTFcuspPec/7dFHuP7Eg==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.12.tgz", + "integrity": "sha512-qBy7OiXOqZrdp88QEl2H4fWalMGnSCrr1agT/AVDndlyw2YJQA89f3ttR/AkEIP9EkBXXeGl6cC72/EZT5r6rw==", "cpu": [ "arm64" ], @@ -4945,9 +4945,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1.tgz", - "integrity": "sha512-fiuN/OG6sNGRN/bRFxRvV5LyzLB8gaL8cbDH5o3mEiVwfcMzyE5T//ilMmaTrnA8HLMS6hoz4cHOu6Qcp9vxgQ==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.12.tgz", + "integrity": "sha512-EfD9L7o9biaQxjwP1uWXnk3vYZi64NVcKUN83hpVkKocB7ogJfyH2r7o1pPnMtir6gHZiGCeHKagJ0yrNSLNHw==", "cpu": [ "arm64" ], @@ -4960,9 +4960,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1.tgz", - "integrity": "sha512-rv6AAdEXoezjbdfp3ouMuVqeLjE1Bin0AuE6qxE6V9g3Giz5/R3xpocHoAi7CufRR+lnkuUjRBn05SYJ83oKNQ==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.12.tgz", + "integrity": "sha512-iQ+n2pxklJew9IpE47hE/VgjmljlHqtcD5UhZVeHICTPbLyrgPehaKf2wLRNjYH75udroBNCgrSSVSVpAbNoYw==", "cpu": [ "x64" ], @@ -4975,9 +4975,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1.tgz", - "integrity": "sha512-YAZLGsaNeChSrpz/G7MxO3TIBLaMN8QWMr3X8bt6rCvKovwU7GqQlDu99WdvF33kI8ZahvcdbFsy4jAFzFX7og==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.12.tgz", + "integrity": "sha512-rFkUkNwcQ0ODn7cxvcVdpHlcOpYxMeyMfkJuzaT74xjAa5v4fxP4xDk5OoYmPi8QNLDs3UgZPMSBmpBuv9zKWA==", "cpu": [ "x64" ], @@ -4990,9 +4990,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1.tgz", - "integrity": "sha512-1L4mUYPBMvVDMZg1inUYyPvFSduot0g73hgfD9CODgbr4xiTYe0VOMTZzaRqYJYBA9mana0x4eaAaypmWo1r5A==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.12.tgz", + "integrity": "sha512-PQFYUvwtHs/u0K85SG4sAdDXYIPXpETf9mcEjWc0R4JmjgMKSDwIU/qfZdavtP6MPNiMjuKGXHCtyhR/M5zo8g==", "cpu": [ "arm64" ], @@ -5005,9 +5005,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1.tgz", - "integrity": "sha512-jvIE9tsuj9vpbbXlR5YxrghRfMuG0Qm/nZ/1KDHc+y6FpnZ/apsgh+G6t15vefU0zp3WSpTMIdXRUsNl/7RSuw==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.12.tgz", + "integrity": "sha512-FAj2hMlcbeCV546eU2tEv41dcJb4NeqFlSXU/xL/0ehXywHnNpaYajOUvn3P8wru5WyQe6cTZ8fvckj/2XN4Vw==", "cpu": [ "ia32" ], @@ -5020,9 +5020,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1.tgz", - "integrity": "sha512-S6K6EHDU5+1KrBDLko7/c1MNy/Ya73pIAmvKeFwsF4RmBFJSO7/7YeD4FnZ4iBdzE69PpQ4sOMU9ORKeNuxe8A==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.12.tgz", + "integrity": "sha512-yu8QvV53sBzoIVRHsxCHqeuS8jYq6Lrmdh0briivuh+Brsp6xjg80MAozUsBTAV9KNmY08KlX0KYTWz1lbPzEg==", "cpu": [ "x64" ], @@ -7048,11 +7048,17 @@ "storybook": "^8.2.9" } }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" + }, "node_modules/@swc/helpers": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", - "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", "dependencies": { + "@swc/counter": "^0.1.3", "tslib": "^2.4.0" } }, @@ -9505,9 +9511,9 @@ "dev": true }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -9517,7 +9523,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -9540,20 +9546,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -12111,9 +12103,9 @@ } }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "engines": { "node": ">= 0.8" } @@ -13783,36 +13775,36 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -13836,20 +13828,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -14036,12 +14014,12 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -19903,9 +19881,12 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -21046,12 +21027,12 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/next": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.1.tgz", - "integrity": "sha512-McrGJqlGSHeaz2yTRPkEucxQKe5Zq7uPwyeHNmJaZNY4wx9E9QdxmTp310agFRoMuIYgQrCrT3petg13fSVOww==", + "version": "14.2.12", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.12.tgz", + "integrity": "sha512-cDOtUSIeoOvt1skKNihdExWMTybx3exnvbFbb9ecZDIxlvIbREQzt9A5Km3Zn3PfU+IFjyYGsHS+lN9VInAGKA==", "dependencies": { - "@next/env": "14.1.1", - "@swc/helpers": "0.5.2", + "@next/env": "14.2.12", + "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "graceful-fs": "^4.2.11", @@ -21065,18 +21046,19 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.1", - "@next/swc-darwin-x64": "14.1.1", - "@next/swc-linux-arm64-gnu": "14.1.1", - "@next/swc-linux-arm64-musl": "14.1.1", - "@next/swc-linux-x64-gnu": "14.1.1", - "@next/swc-linux-x64-musl": "14.1.1", - "@next/swc-win32-arm64-msvc": "14.1.1", - "@next/swc-win32-ia32-msvc": "14.1.1", - "@next/swc-win32-x64-msvc": "14.1.1" + "@next/swc-darwin-arm64": "14.2.12", + "@next/swc-darwin-x64": "14.2.12", + "@next/swc-linux-arm64-gnu": "14.2.12", + "@next/swc-linux-arm64-musl": "14.2.12", + "@next/swc-linux-x64-gnu": "14.2.12", + "@next/swc-linux-x64-musl": "14.2.12", + "@next/swc-win32-arm64-msvc": "14.2.12", + "@next/swc-win32-ia32-msvc": "14.2.12", + "@next/swc-win32-x64-msvc": "14.2.12" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.3.0" @@ -21085,6 +21067,9 @@ "@opentelemetry/api": { "optional": true }, + "@playwright/test": { + "optional": true + }, "sass": { "optional": true } @@ -23369,9 +23354,9 @@ } }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" }, "node_modules/path-type": { "version": "4.0.0", @@ -24544,9 +24529,9 @@ ] }, "node_modules/qs": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", - "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dependencies": { "side-channel": "^1.0.6" }, @@ -26633,9 +26618,9 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -26668,6 +26653,14 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -26682,14 +26675,14 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" diff --git a/package.json b/package.json index b8fe84a48daa..04ba37b586eb 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "generate:dashboard": "node scripts/dashboard/build-dashboard.js", "generate:videos": "node scripts/build-newsroom-videos.js", "generate:tools": "node scripts/build-tools.js", + "test:netlify": "deno test --allow-env --trace-ops netlify/**/*.test.ts", "dev:storybook": "storybook dev -p 6006", "build:storybook": "storybook build" }, @@ -81,7 +82,7 @@ "md5": "^2.3.0", "mermaid": "9.3.0", "moment": "^2.30.1", - "next": "14.1.1", + "next": "14.2.12", "next-i18next": "^15.3.0", "next-language-detector": "^1.1.0", "next-mdx-remote": "^4.4.1", diff --git a/public/img/posts/helsinki-and-community/booth-front.webp b/public/img/posts/helsinki-and-community/booth-front.webp new file mode 100644 index 000000000000..943a62b6b892 Binary files /dev/null and b/public/img/posts/helsinki-and-community/booth-front.webp differ diff --git a/public/img/posts/helsinki-and-community/booth-top.webp b/public/img/posts/helsinki-and-community/booth-top.webp new file mode 100644 index 000000000000..c56fea7f0cde Binary files /dev/null and b/public/img/posts/helsinki-and-community/booth-top.webp differ diff --git a/public/img/posts/helsinki-and-community/hugo.webp b/public/img/posts/helsinki-and-community/hugo.webp new file mode 100644 index 000000000000..f5831b4806d9 Binary files /dev/null and b/public/img/posts/helsinki-and-community/hugo.webp differ diff --git a/public/img/posts/helsinki-and-community/jonas.webp b/public/img/posts/helsinki-and-community/jonas.webp new file mode 100644 index 000000000000..2438bbd81f0c Binary files /dev/null and b/public/img/posts/helsinki-and-community/jonas.webp differ diff --git a/public/img/posts/helsinki-and-community/lukasz.webp b/public/img/posts/helsinki-and-community/lukasz.webp new file mode 100644 index 000000000000..d7cacccd29ca Binary files /dev/null and b/public/img/posts/helsinki-and-community/lukasz.webp differ diff --git a/public/img/posts/helsinki-and-community/run.webp b/public/img/posts/helsinki-and-community/run.webp new file mode 100644 index 000000000000..24f73493ccd0 Binary files /dev/null and b/public/img/posts/helsinki-and-community/run.webp differ diff --git a/types/components/tools/ToolDataType.ts b/types/components/tools/ToolDataType.ts index ef636d09b7e9..3ef659f3c976 100644 --- a/types/components/tools/ToolDataType.ts +++ b/types/components/tools/ToolDataType.ts @@ -41,6 +41,7 @@ export interface ToolsListData { [category: string]: { description: string; toolsList: ToolData[]; + elementRef?: React.RefObject; }; }