diff --git a/.github/workflows/add-scope-to-bet.yml b/.github/workflows/add-scope-to-bet.yml deleted file mode 100644 index 499ad7c3a8..0000000000 --- a/.github/workflows/add-scope-to-bet.yml +++ /dev/null @@ -1,119 +0,0 @@ -name: Add related issues - -on: - issues: - types: - - edited - - opened - -jobs: - add_related_issues: - runs-on: ubuntu-latest - permissions: - issues: write - steps: - - name: Parse Issue Description - id: parse - uses: actions/github-script@v6 - with: - github-token: ${{ secrets.GH_TOKEN }} - result-encoding: json - script: | - const regexSimple = /(Related\sto\s+(\S+)?#(\d+))/; - const description = context.payload.issue.body; - const match = regexSimple.exec(description); - if (!match) { - console.log("Nothing to do in this issue"); - return null; - } - let result = null; - const repoFull = match[2] ? match[2] : context.payload.repository.full_name; - const owner = repoFull.split('/')[0]; - const repo = repoFull.split('/')[1]; - const issueNumber = Number(match[3]); - const repoUrl = `https://github.com/${repoFull}`; - const orgOrUser = context.payload.organization ? 'organization' : 'user'; - const query = ` - query($owner: String!, $repo: String!, $issue: Int!) { - ${orgOrUser}(login: $owner) { - repository(name: $repo) { - issue(number: $issue) { - id - title - body - trackedIssues(first:100) { - nodes { - number - } - } - } - } - } - } - `; - const variables = { - owner, - repo, - issue: issueNumber - } - try { - const data = await github.graphql(query, variables) - const {body, id, trackedIssues} = data[orgOrUser].repository.issue - result = { - issueNumber, - owner, - repo, - repoUrl, - betIssueDescription: body, - issueNodeId: id, - trackedTasks : trackedIssues.nodes.map(issue => issue.number) - }; - } catch (error) { - console.log(`Failed query for issue #${issueNumber}`, error); - } - - return result; - - name: Add The issue to the Bet - id: add-bet - uses: actions/github-script@v6 - if: ${{ steps.parse.outputs.result }} - with: - github-token: ${{ secrets.GH_TOKEN }} - script: | - const results = ${{ steps.parse.outputs.result }}; - if (!results) { - console.log("Nothing to do in this issue - outputs results is null"); - return; - } - const { issueNumber, repo, owner, repoUrl, betIssueDescription, issueNodeId, trackedTasks } = results; - const regex = /###?\sScope([^-]+)((-\s+\[[\sX|x]\]\s*#?.+\s*)+)/; - const match = betIssueDescription.match(regex); - const taskNumber = context.payload.issue.number; - if (!match) { - console.log("Nothing to do in this issue"); - return; - } - const currentScope = match[2].trim(); - const newTask = `- [ ] #${taskNumber}`; - if (trackedTasks.includes(Number(taskNumber))) { - console.log("This issue already exists"); - return; - } - const newScope = `${currentScope}\n${newTask}`; - const newBetDescription = betIssueDescription.replace(currentScope, newScope); - const mutation = `mutation ($input: UpdateIssueInput!) { - updateIssue(input: $input) { - clientMutationId - } - }`; - const variables = { - input : { - id: issueNodeId, - body: newBetDescription - } - }; - try { - await github.graphql(mutation, variables); - } catch (error) { - console.log(`Failed mutation for issue #${issueNodeId}`, error); - } \ No newline at end of file diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 9253675cd6..116b80652d 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -45,7 +45,7 @@ jobs: env: GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" GITHUB_LOGIN: asyncapi-bot - MERGE_LABELS: "" + MERGE_LABELS: "!do-not-merge" MERGE_METHOD: "squash" MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})" MERGE_RETRIES: "20" diff --git a/apps/studio/src/examples/tutorials/invalid.yml b/apps/studio/src/examples/tutorials/invalid.yml index eb950da03d..aa9921099c 100644 --- a/apps/studio/src/examples/tutorials/invalid.yml +++ b/apps/studio/src/examples/tutorials/invalid.yml @@ -1,22 +1,26 @@ # This invalid file exists solely for educational purposes, and if you come across it, here is the tutorial: https://www.asyncapi.com/docs/tutorials/studio-document-validation -asyncapi: '1.0.0' +asyncapi: 3.0.0 info: title: Streetlights API version: '1.0.0' + description: | + The Smartylighting Streetlights API allows you + to remotely manage the city lights. license: name: Apache 2.0 url: 'https://www.apache.org/licenses/LICENSE-2.0' + servers: mosquitto: - url: mqtt://test.mosquitto.org + url: test.mosquitto.org protocol: mqtt + channels: - light/measured: - publish: - summary: Inform about environmental lighting conditions for a particular streetlight. - operationId: onLightMeasured - message: + lightMeasured: + address: 'light/measured' + messages: + lightMeasuredMessage: name: LightMeasured payload: type: object @@ -30,6 +34,13 @@ channels: minimum: 0 description: Light intensity measured in lumens. sentAt: - type: integer + type: string format: date-time description: Date and time when the message was sent. + +operations: + onLightMeasured: + action: 'receive' + summary: Inform about environmental lighting conditions for a particular streetlight. + channel: + $ref: '#/channels/lightMeasured' diff --git a/apps/studio/src/services/app.service.ts b/apps/studio/src/services/app.service.ts index 978c7871b9..bc2dbd8b2f 100644 --- a/apps/studio/src/services/app.service.ts +++ b/apps/studio/src/services/app.service.ts @@ -11,11 +11,12 @@ export class ApplicationService extends AbstractService { // subscribe to state to hide preloader this.hidePreloader(); - const { readOnly, url, base64 } = this.svcs.navigationSvc.getUrlParameters(); + const { readOnly, url, base64 } = + this.svcs.navigationSvc.getUrlParameters(); // readOnly state should be only set to true when someone pass also url or base64 parameter const isStrictReadonly = Boolean(readOnly && (url || base64)); - let error: any; + let error: any; try { await this.fetchResource(url, base64); } catch (err) { @@ -23,6 +24,10 @@ export class ApplicationService extends AbstractService { console.error(err); } + if (error) { + appState.setState({ initErrors: [error] }); + } + if (isStrictReadonly && !error) { appState.setState({ readOnly, @@ -32,7 +37,8 @@ export class ApplicationService extends AbstractService { } public async afterAppInit() { - const { readOnly, url, base64, redirectedFrom } = this.svcs.navigationSvc.getUrlParameters(); + const { readOnly, url, base64, redirectedFrom } = + this.svcs.navigationSvc.getUrlParameters(); const isStrictReadonly = Boolean(readOnly && (url || base64)); // show RedirectedModal modal if the redirectedFrom is set (only when readOnly state is set to false) @@ -45,11 +51,11 @@ export class ApplicationService extends AbstractService { if (!url && !base64) { return; } - + const { updateFile } = filesState.getState(); let content = ''; if (url) { - content = await fetch(url).then(res => res.text()); + content = await fetch(url).then((res) => res.text()); } else if (base64) { content = this.svcs.formatSvc.decodeBase64(base64); } @@ -79,4 +85,4 @@ export class ApplicationService extends AbstractService { } }); } -} \ No newline at end of file +} diff --git a/apps/studio/src/state/app.state.ts b/apps/studio/src/state/app.state.ts index 3ebeab6c04..40af06b1ba 100644 --- a/apps/studio/src/state/app.state.ts +++ b/apps/studio/src/state/app.state.ts @@ -4,12 +4,14 @@ export type AppState = { initialized: boolean; readOnly: boolean; liveServer: boolean; + initErrors: any[], } export const appState = create(() => ({ initialized: false, readOnly: false, liveServer: false, + initErrors: [], })); export const useAppState = appState; \ No newline at end of file diff --git a/apps/studio/src/studio.tsx b/apps/studio/src/studio.tsx index 8837af4c9c..ba60207fcf 100644 --- a/apps/studio/src/studio.tsx +++ b/apps/studio/src/studio.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import { Toaster } from 'react-hot-toast'; +import toast, { Toaster } from 'react-hot-toast'; import { Content, Sidebar, Template, Toolbar } from './components'; @@ -8,7 +8,9 @@ import { appState } from './state'; export interface AsyncAPIStudioProps {} -export const AsyncAPIStudio: React.FunctionComponent = () => { +export const AsyncAPIStudio: React.FunctionComponent< + AsyncAPIStudioProps +> = () => { const services = useServices(); useEffect(() => { @@ -24,6 +26,13 @@ export const AsyncAPIStudio: React.FunctionComponent = () = ); } + const unsubscribe = appState.subscribe((state) => { + state.initErrors.forEach((e) => { + toast.error(e.message); + }); + unsubscribe(); + appState.setState({ initErrors: [] }); + }); return (