From 915f8080d24cc627ab51af47d960564592973fc1 Mon Sep 17 00:00:00 2001 From: Animesh Kumar Date: Fri, 7 Jun 2024 14:30:50 +0530 Subject: [PATCH] chore: copy files from test branch Changes: - copied files from test branch: https://github.com/AnimeshKumar923/asyncapi-spec/tree/embedded-examples-jsonPath-test/scripts/validation - copied because merge conflict and older files in the previous branch - files required for validation of embedded examples - still a WIP, more modification and refinement will be made in future --- scripts/validation/base-document.json | 576 +++++ scripts/validation/base-document.yaml | 336 +++ .../embedded-jsonPath-replacement.js | 91 + .../embedded-files-test/ex-base-doc.json | 571 +++++ .../embedded-files-test/ex-doc-v1.md | 42 + .../embedded-files-test/gpt-prompt.md | 4 + .../embedded-files-test/updated-doc.json | 600 +++++ scripts/validation/package-lock.json | 1921 +++++++++++++++++ scripts/validation/package.json | 17 + scripts/validation/script-v1.js | 68 + scripts/validation/script-v2.js | 91 + scripts/validation/test-02.json | 68 + scripts/validation/test-document.md | 22 + .../validation/validate-embedded-examples.js | 62 + 14 files changed, 4469 insertions(+) create mode 100644 scripts/validation/base-document.json create mode 100644 scripts/validation/base-document.yaml create mode 100644 scripts/validation/embedded-files-test/embedded-jsonPath-replacement.js create mode 100644 scripts/validation/embedded-files-test/ex-base-doc.json create mode 100644 scripts/validation/embedded-files-test/ex-doc-v1.md create mode 100644 scripts/validation/embedded-files-test/gpt-prompt.md create mode 100644 scripts/validation/embedded-files-test/updated-doc.json create mode 100644 scripts/validation/package-lock.json create mode 100644 scripts/validation/package.json create mode 100644 scripts/validation/script-v1.js create mode 100644 scripts/validation/script-v2.js create mode 100644 scripts/validation/test-02.json create mode 100644 scripts/validation/test-document.md create mode 100644 scripts/validation/validate-embedded-examples.js diff --git a/scripts/validation/base-document.json b/scripts/validation/base-document.json new file mode 100644 index 00000000..725063c9 --- /dev/null +++ b/scripts/validation/base-document.json @@ -0,0 +1,576 @@ +{ + "asyncapi": "3.0.0", + "info": { + "title": "AsyncAPI Sample App", + "version": "1.0.1", + "description": "This is a sample app.", + "termsOfService": "https://asyncapi.org/terms/", + "contact": { + "name": "API Support", + "url": "https://www.asyncapi.org/support", + "email": "support@asyncapi.org" + }, + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + }, + "externalDocs": { + "description": "Find more info here", + "url": "https://www.asyncapi.org" + }, + "tags": [ + { + "name": "e-commerce" + } + ] + }, + "servers": { + "production": { + "host": "rabbitmq.in.mycompany.com:5672", + "pathname": "/v1", + "protocol": "amqp", + "protocolVersion": "1.0", + "description": "Production RabbitMQ broker (uses the `production` vhost).", + "title": "Production Server", + "summary": "Production environment server", + "security": [ + { + "type": "http", + "scheme": "bearer" + } + ], + "tags": [ + { + "name": "production", + "description": "Production environment" + } + ], + "externalDocs": { + "description": "Additional documentation for the production server", + "url": "https://example.com/docs/production" + }, + "bindings": { + "amqp": { + "exchange": "my-exchange", + "queue": "my-queue" + } + } + }, + "staging": { + "host": "rabbitmq.in.mycompany.com:5672", + "pathname": "/v1", + "protocol": "amqp", + "protocolVersion": "1.0", + "description": "Staging RabbitMQ broker (uses the `staging` vhost).", + "title": "Staging Server", + "summary": "Staging environment server", + "security": [ + { + "type": "apiKey", + "in": "user", + "description": "Provide your API key as the user and leave the password empty." + } + ], + "tags": [ + { + "name": "staging", + "description": "Staging environment" + } + ], + "externalDocs": { + "description": "Additional documentation for the staging server", + "url": "https://example.com/docs/staging" + }, + "bindings": { + "amqp": { + "exchange": "my-exchange", + "queue": "my-queue" + } + } + } + }, + "channels": { + "user": { + "address": "users.{userId}", + "title": "Users channel", + "description": "This channel is used to exchange messages about user events.", + "messages": { + "userSignedUp": { + "$ref": "#/components/messages/userSignedUp" + }, + "userCompletedOrder": { + "$ref": "#/components/messages/userCompletedOrder" + } + }, + "parameters": { + "userId": { + "$ref": "#/components/parameters/userId" + } + }, + "servers": [ + { + "$ref": "#/servers/production" + } + ], + "bindings": { + "amqp": { + "is": "queue", + "queue": { + "exclusive": true + } + } + }, + "tags": [ + { + "name": "user", + "description": "User-related messages" + } + ], + "externalDocs": { + "description": "Find more info here", + "url": "https://example.com" + } + }, + "userSignupReply": { + "address": "users.signup.reply", + "description": "Channel for user signup replies", + "messages": { + "userSignedUpReply": { + "summary": "User signup reply message", + "payload": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "Status of the signup process" + }, + "message": { + "type": "string", + "description": "Additional information" + } + } + } + } + } + } + }, + "operations": { + "sendUserSignUp": { + "action": "send", + "title": "User sign up", + "summary": "Action to sign a user up.", + "description": "A longer description", + "channel": { + "$ref": "#/channels/user" + }, + "security": [ + { + "type": "oauth2", + "description": "The oauth security descriptions", + "flows": { + "clientCredentials": { + "tokenUrl": "https://example.com/api/oauth/dialog", + "availableScopes": { + "subscribe:auth_revocations": "Scope required for authorization revocation topic" + } + } + }, + "scopes": [ + "subscribe:auth_revocations" + ] + } + ], + "tags": [ + { + "name": "user" + }, + { + "name": "signup" + }, + { + "name": "register" + } + ], + "bindings": { + "amqp": { + "ack": false + } + }, + "messages": [ + { + "$ref": "#/channels/user/messages/userSignedUp" + } + ], + "reply": { + "address": { + "location": "$message.header#/replyTo" + }, + "channel": { + "$ref": "#/channels/userSignupReply" + }, + "messages": [ + { + "$ref": "#/channels/userSignupReply/messages/userSignedUpReply" + } + ] + } + } + }, + "components": { + "schemas": { + "Category": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + } + } + }, + "AvroExample": { + "schemaFormat": "application/vnd.apache.avro+json;version=1.9.0", + "schema": { + "type": "record", + "name": "UserCreate", + "namespace": "com.example", + "fields": [ + { + "name": "id", + "type": "int" + }, + { + "name": "name", + "type": "string" + } + ] + } + }, + "userCreate": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The ID of the user" + }, + "name": { + "type": "string", + "description": "The name of the user" + }, + "email": { + "type": "string", + "format": "email", + "description": "The email of the user" + } + }, + "required": ["id", "name", "email"] + }, + "signup": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "format": "date-time", + "description": "The timestamp of the signup" + }, + "source": { + "type": "string", + "description": "The source of the signup" + } + }, + "required": ["timestamp", "source"] + } + }, + "servers": { + "development": { + "host": "{stage}.in.mycompany.com", + "protocol": "amqp", + "description": "RabbitMQ broker", + "bindings": { + "$ref": "#/components/serverBindings/devAmqp" + }, + "variables": { + "stage": { + "$ref": "#/components/serverVariables/stage" + } + }, + "security": [ + { + "$ref": "#/components/securitySchemes/oauth" + } + ] + } + }, + "serverVariables": { + "stage": { + "default": "demo", + "description": "This value is assigned by the service provider in this example of `mycompany.com`" + } + }, + "channels": { + "user": { + "address": "users.{userId}", + "title": "Users channel", + "description": "This channel is used to exchange messages about user events.", + "messages": { + "userSignedUp": { + "$ref": "#/components/messages/userSignUp" + } + }, + "parameters": { + "userId": { + "$ref": "#/components/parameters/userId" + } + }, + "servers": [ + { + "$ref": "#/components/servers/development" + } + ], + "bindings": { + "$ref": "#/components/channelBindings/user" + }, + "tags": [ + { + "$ref": "#/components/tags/user" + } + ], + "externalDocs": { + "$ref": "#/components/externalDocs/infoDocs" + } + } + }, + "messages": { + "userSignUp": { + "summary": "Action to sign a user up.", + "traits": [ + { + "$ref": "#/components/messageTraits/commonHeaders" + } + ], + "payload": { + "$ref": "#/components/schemas/Category" + }, + "correlationId": { + "$ref": "#/components/correlationIds/default" + }, + "bindings": { + "$ref": "#/components/messageBindings/user" + } + }, + "userSignedUp": { + "name": "UserSignup", + "title": "User signup", + "summary": "Action to sign a user up.", + "description": "A longer description", + "contentType": "application/json", + "tags": [ + { "name": "user" }, + { "name": "signup" }, + { "name": "register" } + ], + "headers": { + "type": "object", + "properties": { + "correlationId": { + "description": "Correlation ID set by application", + "type": "string" + }, + "applicationInstanceId": { + "description": "Unique identifier for a given instance of the publishing application", + "type": "string" + } + } + }, + "payload": { + "type": "object", + "properties": { + "user": { + "$ref": "#/components/schemas/userCreate" + }, + "signup": { + "$ref": "#/components/schemas/signup" + } + } + }, + "correlationId": { + "description": "Default Correlation ID", + "location": "$message.header#/correlationId" + }, + "traits": [ + { "$ref": "#/components/messageTraits/commonHeaders" } + ], + "examples": [ + { + "name": "SimpleSignup", + "summary": "A simple UserSignup example message", + "headers": { + "correlationId": "my-correlation-id", + "applicationInstanceId": "myInstanceId" + }, + "payload": { + "user": { + "someUserKey": "someUserValue" + }, + "signup": { + "someSignupKey": "someSignupValue" + } + } + } + ] + }, + "userCompletedOrder": { + "summary": "User completed order event", + "contentType": "application/json", + "payload": { + "type": "object", + "properties": { + "orderId": { + "type": "string", + "description": "The ID of the order" + }, + "userId": { + "type": "string", + "description": "The ID of the user" + }, + "amount": { + "type": "number", + "description": "The total amount of the order" + } + } + } + } + }, + "parameters": { + "userId": { + "description": "Id of the user." + } + }, + "correlationIds": { + "default": { + "description": "Default Correlation ID", + "location": "$message.header#/correlationId" + } + }, + "operations": { + "sendUserSignUp": { + "action": "send", + "title": "User sign up", + "channel": { + "$ref": "#/channels/user" + }, + "bindings": { + "$ref": "#/components/operationBindings/sendUser" + }, + "traits": [ + { + "$ref": "#/components/operationTraits/binding" + } + ], + "reply": { + "$ref": "#/components/replies/signupReply" + } + } + }, + "replies": { + "signupReply": { + "address": { + "$ref": "#/components/replyAddresses/signupReply" + }, + "channel": { + "$ref": "#/channels/userSignupReply" + } + } + }, + "replyAddresses": { + "signupReply": { + "location": "$message.header#/replyTo" + } + }, + "securitySchemes": { + "oauth": { + "type": "oauth2", + "description": "The oauth security descriptions", + "flows": { + "clientCredentials": { + "tokenUrl": "https://example.com/api/oauth/dialog", + "availableScopes": { + "subscribe:auth_revocations": "Scope required for authorization revocation topic" + } + } + }, + "scopes": [ + "subscribe:auth_revocations" + ] + } + }, + "operationTraits": { + "binding": { + "bindings": { + "amqp": { + "ack": false + } + } + } + }, + "messageTraits": { + "commonHeaders": { + "headers": { + "type": "object", + "properties": { + "my-app-header": { + "type": "integer", + "minimum": 0, + "maximum": 100 + } + } + } + } + }, + "tags": { + "user": { + "name": "user", + "description": "User-related messages" + } + }, + "externalDocs": { + "infoDocs": { + "url": "https://example.com/docs", + "description": "Find more info here" + } + }, + "serverBindings": { + "devAmqp": { + "amqp": { + "exchange": "my-exchange", + "queue": "my-queue" + } + } + }, + "channelBindings": { + "user": { + "amqp": { + "is": "queue", + "queue": { + "exclusive": true + } + } + } + }, + "operationBindings": { + "sendUser": { + "amqp": { + "ack": false + } + } + }, + "messageBindings": { + "user": { + "amqp": { + "contentEncoding": "gzip", + "messageType": "user.signup", + "bindingVersion": "0.3.0" + } + } + } + } +} \ No newline at end of file diff --git a/scripts/validation/base-document.yaml b/scripts/validation/base-document.yaml new file mode 100644 index 00000000..513610df --- /dev/null +++ b/scripts/validation/base-document.yaml @@ -0,0 +1,336 @@ +asyncapi: 3.0.0 +info: + title: My Event-Driven API + version: 1.0.0 + description: This API provides real-time event streaming capabilities. + termsOfService: https://example.com/terms-of-service + contact: + name: Rohit + email: rohitwashere@asyncapi.com + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + tags: + - name: Events + description: APIs related to event streaming + - name: Authentication + description: APIs for authentication and authorization + externalDocs: + description: Additional documentation + url: https://example.com/docs +servers: + production: + host: rabbitmq.in.mycompany.com:5672 + pathname: /v1 + protocol: amqp + protocolVersion: "1.0" + description: Production RabbitMQ broker (uses the `production` vhost). + title: Production Server + summary: Production environment server + security: + - type: http + scheme: bearer + tags: + - name: production + description: Production environment + externalDocs: + description: Additional documentation for the production server + url: https://example.com/docs/production + bindings: + amqp: + exchange: my-exchange + queue: my-queue + staging: + host: rabbitmq.in.mycompany.com:5672 + pathname: /v1 + protocol: amqp + protocolVersion: "1.0" + description: Staging RabbitMQ broker (uses the `staging` vhost). + title: Staging Server + summary: Staging environment server + security: + - type: apiKey + in: user + description: Provide your API key as the user and leave the password empty. + tags: + - name: staging + description: Staging environment + externalDocs: + description: Additional documentation for the staging server + url: https://example.com/docs/staging + bindings: + amqp: + exchange: my-exchange + queue: my-queue +channels: + user: + address: 'users.{userId}' + title: Users channel + description: This channel is used to exchange messages about user events. + messages: + userSignedUp: + $ref: '#/components/messages/userSignedUp' + userCompletedOrder: + $ref: '#/components/messages/userCompletedOrder' + parameters: + userId: + $ref: '#/components/parameters/userId' + servers: + - $ref: '#/servers/production' + bindings: + amqp: + is: queue + queue: + exclusive: true + tags: + - name: user + description: User-related messages + externalDocs: + description: 'Find more info here' + url: 'https://example.com' + userSignupReply: + address: 'users.signup.reply' + description: Channel for user signup replies + messages: + userSignedUpReply: + summary: User signup reply message + payload: + type: object + properties: + status: + type: string + description: Status of the signup process + message: + type: string + description: Additional information + + +operations: + sendUserSignUp: + action: send + title: User sign up + summary: Action to sign a user up. + description: A longer description + channel: + $ref: '#/channels/user' + security: + - type: oauth2 + description: The oauth security descriptions + flows: + clientCredentials: + tokenUrl: 'https://example.com/api/oauth/dialog' + availableScopes: + 'subscribe:auth_revocations': Scope required for authorization revocation topic + scopes: + - 'subscribe:auth_revocations' + tags: + - name: user + - name: signup + - name: register + bindings: + amqp: + ack: false + messages: + - $ref: '#/channels/user/messages/userSignedUp' + reply: + address: + location: '$message.header#/replyTo' + channel: + $ref: '#/channels/userSignupReply' + messages: + - $ref: '#/channels/userSignupReply/messages/userSignedUpReply' + +components: + schemas: + Category: + type: object + properties: + id: + type: integer + format: int64 + AvroExample: + schemaFormat: application/vnd.apache.avro+json;version=1.9.0 + schema: + type: record + name: UserCreate + namespace: com.example + fields: + - name: id + type: int + - name: name + type: string + + servers: + development: + host: '{stage}.in.mycompany.com' + protocol: amqp + description: RabbitMQ broker + bindings: + $ref: '#/components/serverBindings/devAmqp' + variables: + stage: + $ref: '#/components/serverVariables/stage' + security: + - $ref: '#/components/securitySchemes/oauth' + + serverVariables: + stage: + default: demo + description: This value is assigned by the service provider in this example of `mycompany.com` + + channels: + user: + address: 'users.{userId}' + title: Users channel + description: This channel is used to exchange messages about user events. + messages: + userSignedUp: + $ref: '#/components/messages/userSignUp' + parameters: + userId: + $ref: '#/components/parameters/userId' + servers: + - $ref: '#/components/servers/development' + bindings: + $ref: '#/components/channelBindings/user' + tags: + - $ref: '#/components/tags/user' + externalDocs: + $ref: '#/components/externalDocs/infoDocs' + + messages: + userSignUp: + summary: Action to sign a user up. + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: '#/components/schemas/Category' + correlationId: + $ref: '#/components/correlationIds/default' + bindings: + $ref: '#/components/messageBindings/user' + userSignedUp: + summary: User signed up event + contentType: application/json + payload: + type: object + properties: + userId: + type: string + description: The ID of the user + email: + type: string + description: The email of the user + userCompletedOrder: + summary: User completed order event + contentType: application/json + payload: + type: object + properties: + orderId: + type: string + description: The ID of the order + userId: + type: string + description: The ID of the user + amount: + type: number + description: The total amount of the order + + + parameters: + userId: + description: Id of the user. + + correlationIds: + default: + description: Default Correlation ID + location: '$message.header#/correlationId' + + operations: + sendUserSignUp: + action: send + title: User sign up + channel: + $ref: '#/channels/user' + bindings: + $ref: '#/components/operationBindings/sendUser' + traits: + - $ref: '#/components/operationTraits/binding' + reply: + $ref: '#/components/replies/signupReply' + + replies: + signupReply: + address: + $ref: '#/components/replyAddresses/signupReply' + channel: + $ref: '#/channels/userSignupReply' + + replyAddresses: + signupReply: + location: '$message.header#/replyTo' + + + securitySchemes: + oauth: + type: oauth2 + description: The oauth security descriptions + flows: + clientCredentials: + tokenUrl: 'https://example.com/api/oauth/dialog' + availableScopes: + 'subscribe:auth_revocations': Scope required for authorization revocation topic + scopes: + - 'subscribe:auth_revocations' + + operationTraits: + binding: + bindings: + amqp: + ack: false + + messageTraits: + commonHeaders: + headers: + type: object + properties: + my-app-header: + type: integer + minimum: 0 + maximum: 100 + + tags: + user: + name: user + description: User-related messages + + externalDocs: + infoDocs: + url: https://example.com/docs + description: 'Find more info here' + + serverBindings: + devAmqp: + amqp: + exchange: my-exchange + queue: my-queue + + channelBindings: + user: + amqp: + is: queue + queue: + exclusive: true + + operationBindings: + sendUser: + amqp: + ack: false + + messageBindings: + user: + amqp: + contentEncoding: gzip + messageType: 'user.signup' + bindingVersion: '0.3.0' \ No newline at end of file diff --git a/scripts/validation/embedded-files-test/embedded-jsonPath-replacement.js b/scripts/validation/embedded-files-test/embedded-jsonPath-replacement.js new file mode 100644 index 00000000..b08529e5 --- /dev/null +++ b/scripts/validation/embedded-files-test/embedded-jsonPath-replacement.js @@ -0,0 +1,91 @@ +const fs = require('fs'); +const { JSONPath } = require('jsonpath-plus'); + +// Read the markdown file +const markdownContent = fs.readFileSync('ex-doc-v1.md', 'utf8'); + +// Function to extract comments with example metadata +function extractComments(content) { + const commentRegex = //g; + let match; + const comments = []; + + while ((match = commentRegex.exec(content)) !== null) { + try { + comments.push(JSON.parse(match[1])); + } catch (e) { + console.error("Failed to parse comment JSON:", match[1], e); + } + } + + return comments; +} + +// Extract comments from the markdown file +const comments = extractComments(markdownContent); + +// Function to extract JSON examples from markdown content +function extractExamples(content) { + const exampleRegex = /```json\s+([\s\S]*?)\s+```/g; + let match; + const examples = []; + + while ((match = exampleRegex.exec(content)) !== null) { + examples.push(JSON.parse(match[1])); + } + + return examples; +} + +// Extract examples from the markdown file +const examples = extractExamples(markdownContent); + +// Read the base AsyncAPI document for v3 +const baseDoc = JSON.parse(fs.readFileSync('ex-base-doc.json', 'utf8')); + +// Function to set a value in a JSON object using JSONPath, creating missing fields if necessary +function setValueByPath(obj, path, value) { + const pathParts = path.replace(/\$/g, '').split('.').slice(1); // Remove the root "$" and split path + let current = obj; + + pathParts.forEach((part, index) => { + if (index === pathParts.length - 1) { + current[part] = value; // Set value at the end of the path + } else { + if (!current[part]) { + current[part] = {}; // Create object if it doesn't exist + } + current = current[part]; + } + }); +} + +// Create updates array from comments and examples +const updates = comments.map((comment, index) => ({ + json_path: comment.json_path, + data: examples[index], + test: comment.test +})); + +// Apply updates +updates.forEach(update => { + const results = JSONPath({ path: update.json_path, json: baseDoc, resultType: 'all' }); + + if (results.length === 0) { + setValueByPath(baseDoc, update.json_path, update.data); // Create the path if it doesn't exist + } else { + results.forEach(result => { + const parent = result.parent; + const parentProperty = result.parentProperty; + parent[parentProperty] = { + ...parent[parentProperty], + ...update.data // Merge the existing data with the new data + }; + }); + } +}); + +// Save the updated document +fs.writeFileSync('updated-doc.json', JSON.stringify(baseDoc, null, 2), 'utf8'); + +console.log('AsyncAPI v3 document updated successfully!'); diff --git a/scripts/validation/embedded-files-test/ex-base-doc.json b/scripts/validation/embedded-files-test/ex-base-doc.json new file mode 100644 index 00000000..985eabae --- /dev/null +++ b/scripts/validation/embedded-files-test/ex-base-doc.json @@ -0,0 +1,571 @@ +{ + "asyncapi": "3.0.0", + "info": { + "title": "AsyncAPI", + "version": "1.9.5", + "description": "This is a very good doc, probably.", + "termsOfService": "https://asyncapi.org/terms/", + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + }, + "externalDocs": { + "description": "Find more info here", + "url": "https://www.asyncapi.org" + }, + "tags": [ + { + "name": "e-commerce" + } + ] + }, + "servers": { + "production": { + "host": "rabbitmq.in.mycompany.com:5672", + "pathname": "/v1", + "protocol": "amqp", + "protocolVersion": "1.0", + "description": "Production RabbitMQ broker (uses the `production` vhost).", + "title": "Production Server", + "summary": "Production environment server", + "security": [ + { + "type": "http", + "scheme": "bearer" + } + ], + "tags": [ + { + "name": "production", + "description": "Production environment" + } + ], + "externalDocs": { + "description": "Additional documentation for the production server", + "url": "https://example.com/docs/production" + }, + "bindings": { + "amqp": { + "exchange": "my-exchange", + "queue": "my-queue" + } + } + }, + "staging": { + "host": "rabbitmq.in.mycompany.com:5672", + "pathname": "/v1", + "protocol": "amqp", + "protocolVersion": "1.0", + "description": "Staging RabbitMQ broker (uses the `staging` vhost).", + "title": "Staging Server", + "summary": "Staging environment server", + "security": [ + { + "type": "apiKey", + "in": "user", + "description": "Provide your API key as the user and leave the password empty." + } + ], + "tags": [ + { + "name": "staging", + "description": "Staging environment" + } + ], + "externalDocs": { + "description": "Additional documentation for the staging server", + "url": "https://example.com/docs/staging" + }, + "bindings": { + "amqp": { + "exchange": "my-exchange", + "queue": "my-queue" + } + } + } + }, + "channels": { + "user": { + "address": "users.{userId}", + "title": "Users channel", + "description": "This channel is used to exchange messages about user events.", + "messages": { + "userSignedUp": { + "$ref": "#/components/messages/userSignedUp" + }, + "userCompletedOrder": { + "$ref": "#/components/messages/userCompletedOrder" + } + }, + "parameters": { + "userId": { + "$ref": "#/components/parameters/userId" + } + }, + "servers": [ + { + "$ref": "#/servers/production" + } + ], + "bindings": { + "amqp": { + "is": "queue", + "queue": { + "exclusive": true + } + } + }, + "tags": [ + { + "name": "user", + "description": "User-related messages" + } + ], + "externalDocs": { + "description": "Find more info here", + "url": "https://example.com" + } + }, + "userSignupReply": { + "address": "users.signup.reply", + "description": "Channel for user signup replies", + "messages": { + "userSignedUpReply": { + "summary": "User signup reply message", + "payload": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "Status of the signup process" + }, + "message": { + "type": "string", + "description": "Additional information" + } + } + } + } + } + } + }, + "operations": { + "sendUserSignUp": { + "action": "send", + "title": "User sign up", + "summary": "Action to sign a user up.", + "description": "A longer description", + "channel": { + "$ref": "#/channels/user" + }, + "security": [ + { + "type": "oauth2", + "description": "The oauth security descriptions", + "flows": { + "clientCredentials": { + "tokenUrl": "https://example.com/api/oauth/dialog", + "availableScopes": { + "subscribe:auth_revocations": "Scope required for authorization revocation topic" + } + } + }, + "scopes": [ + "subscribe:auth_revocations" + ] + } + ], + "tags": [ + { + "name": "user" + }, + { + "name": "signup" + }, + { + "name": "register" + } + ], + "bindings": { + "amqp": { + "ack": false + } + }, + "messages": [ + { + "$ref": "#/channels/user/messages/userSignedUp" + } + ], + "reply": { + "address": { + "location": "$message.header#/replyTo" + }, + "channel": { + "$ref": "#/channels/userSignupReply" + }, + "messages": [ + { + "$ref": "#/channels/userSignupReply/messages/userSignedUpReply" + } + ] + } + } + }, + "components": { + "schemas": { + "Category": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + } + } + }, + "AvroExample": { + "schemaFormat": "application/vnd.apache.avro+json;version=1.9.0", + "schema": { + "type": "record", + "name": "UserCreate", + "namespace": "com.example", + "fields": [ + { + "name": "id", + "type": "int" + }, + { + "name": "name", + "type": "string" + } + ] + } + }, + "userCreate": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The ID of the user" + }, + "name": { + "type": "string", + "description": "The name of the user" + }, + "email": { + "type": "string", + "format": "email", + "description": "The email of the user" + } + }, + "required": ["id", "name", "email"] + }, + "signup": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "format": "date-time", + "description": "The timestamp of the signup" + }, + "source": { + "type": "string", + "description": "The source of the signup" + } + }, + "required": ["timestamp", "source"] + } + }, + "servers": { + "development": { + "host": "{stage}.in.mycompany.com", + "protocol": "amqp", + "description": "RabbitMQ broker", + "bindings": { + "$ref": "#/components/serverBindings/devAmqp" + }, + "variables": { + "stage": { + "$ref": "#/components/serverVariables/stage" + } + }, + "security": [ + { + "$ref": "#/components/securitySchemes/oauth" + } + ] + } + }, + "serverVariables": { + "stage": { + "default": "demo", + "description": "This value is assigned by the service provider in this example of `mycompany.com`" + } + }, + "channels": { + "user": { + "address": "users.{userId}", + "title": "Users channel", + "description": "This channel is used to exchange messages about user events.", + "messages": { + "userSignedUp": { + "$ref": "#/components/messages/userSignUp" + } + }, + "parameters": { + "userId": { + "$ref": "#/components/parameters/userId" + } + }, + "servers": [ + { + "$ref": "#/components/servers/development" + } + ], + "bindings": { + "$ref": "#/components/channelBindings/user" + }, + "tags": [ + { + "$ref": "#/components/tags/user" + } + ], + "externalDocs": { + "$ref": "#/components/externalDocs/infoDocs" + } + } + }, + "messages": { + "userSignUp": { + "summary": "Action to sign a user up.", + "traits": [ + { + "$ref": "#/components/messageTraits/commonHeaders" + } + ], + "payload": { + "$ref": "#/components/schemas/Category" + }, + "correlationId": { + "$ref": "#/components/correlationIds/default" + }, + "bindings": { + "$ref": "#/components/messageBindings/user" + } + }, + "userSignedUp": { + "name": "UserSignup", + "title": "User signup", + "summary": "Action to sign a user up.", + "description": "A longer description", + "contentType": "application/json", + "tags": [ + { "name": "user" }, + { "name": "signup" }, + { "name": "register" } + ], + "headers": { + "type": "object", + "properties": { + "correlationId": { + "description": "Correlation ID set by application", + "type": "string" + }, + "applicationInstanceId": { + "description": "Unique identifier for a given instance of the publishing application", + "type": "string" + } + } + }, + "payload": { + "type": "object", + "properties": { + "user": { + "$ref": "#/components/schemas/userCreate" + }, + "signup": { + "$ref": "#/components/schemas/signup" + } + } + }, + "correlationId": { + "description": "Default Correlation ID", + "location": "$message.header#/correlationId" + }, + "traits": [ + { "$ref": "#/components/messageTraits/commonHeaders" } + ], + "examples": [ + { + "name": "SimpleSignup", + "summary": "A simple UserSignup example message", + "headers": { + "correlationId": "my-correlation-id", + "applicationInstanceId": "myInstanceId" + }, + "payload": { + "user": { + "someUserKey": "someUserValue" + }, + "signup": { + "someSignupKey": "someSignupValue" + } + } + } + ] + }, + "userCompletedOrder": { + "summary": "User completed order event", + "contentType": "application/json", + "payload": { + "type": "object", + "properties": { + "orderId": { + "type": "string", + "description": "The ID of the order" + }, + "userId": { + "type": "string", + "description": "The ID of the user" + }, + "amount": { + "type": "number", + "description": "The total amount of the order" + } + } + } + } + }, + "parameters": { + "userId": { + "description": "Id of the user." + } + }, + "correlationIds": { + "default": { + "description": "Default Correlation ID", + "location": "$message.header#/correlationId" + } + }, + "operations": { + "sendUserSignUp": { + "action": "send", + "title": "User sign up", + "channel": { + "$ref": "#/channels/user" + }, + "bindings": { + "$ref": "#/components/operationBindings/sendUser" + }, + "traits": [ + { + "$ref": "#/components/operationTraits/binding" + } + ], + "reply": { + "$ref": "#/components/replies/signupReply" + } + } + }, + "replies": { + "signupReply": { + "address": { + "$ref": "#/components/replyAddresses/signupReply" + }, + "channel": { + "$ref": "#/channels/userSignupReply" + } + } + }, + "replyAddresses": { + "signupReply": { + "location": "$message.header#/replyTo" + } + }, + "securitySchemes": { + "oauth": { + "type": "oauth2", + "description": "The oauth security descriptions", + "flows": { + "clientCredentials": { + "tokenUrl": "https://example.com/api/oauth/dialog", + "availableScopes": { + "subscribe:auth_revocations": "Scope required for authorization revocation topic" + } + } + }, + "scopes": [ + "subscribe:auth_revocations" + ] + } + }, + "operationTraits": { + "binding": { + "bindings": { + "amqp": { + "ack": false + } + } + } + }, + "messageTraits": { + "commonHeaders": { + "headers": { + "type": "object", + "properties": { + "my-app-header": { + "type": "integer", + "minimum": 0, + "maximum": 100 + } + } + } + } + }, + "tags": { + "user": { + "name": "user", + "description": "User-related messages" + } + }, + "externalDocs": { + "infoDocs": { + "url": "https://example.com/docs", + "description": "Find more info here" + } + }, + "serverBindings": { + "devAmqp": { + "amqp": { + "exchange": "my-exchange", + "queue": "my-queue" + } + } + }, + "channelBindings": { + "user": { + "amqp": { + "is": "queue", + "queue": { + "exclusive": true + } + } + } + }, + "operationBindings": { + "sendUser": { + "amqp": { + "ack": false + } + } + }, + "messageBindings": { + "user": { + "amqp": { + "contentEncoding": "gzip", + "messageType": "user.signup", + "bindingVersion": "0.3.0" + } + } + } + } +} \ No newline at end of file diff --git a/scripts/validation/embedded-files-test/ex-doc-v1.md b/scripts/validation/embedded-files-test/ex-doc-v1.md new file mode 100644 index 00000000..2942bd04 --- /dev/null +++ b/scripts/validation/embedded-files-test/ex-doc-v1.md @@ -0,0 +1,42 @@ +# AsyncAPI Examples + +## Operations Object + +Here is an example of an operations object: + + +```json +{ + "name": "API Support", + "url": "https://www.example.com/support", + "email": "support@example.com" +} +``` + + +```json +{ + "title": "AsyncAPI Sample App", + "version": "1.0.1", + "description": "This is a sample app.", + "termsOfService": "https://asyncapi.org/terms/", + "contact": { + "name": "API Support", + "url": "https://www.asyncapi.org/support", + "email": "support@asyncapi.org" + }, + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + }, + "externalDocs": { + "description": "Find more info here", + "url": "https://www.asyncapi.org" + }, + "tags": [ + { + "name": "e-commerce" + } + ] +} +``` \ No newline at end of file diff --git a/scripts/validation/embedded-files-test/gpt-prompt.md b/scripts/validation/embedded-files-test/gpt-prompt.md new file mode 100644 index 00000000..89b26608 --- /dev/null +++ b/scripts/validation/embedded-files-test/gpt-prompt.md @@ -0,0 +1,4 @@ +so the plan is we have examples in a big spec document which is in markdown and has embedded examples in it. Then we manually add comments on the examples that we want to validate. The document in which the comment will be added is in the markdown format so the comments will be in this format `` here `test` will be the name of the example being worked upon which can be treated as metadata to show in errors or logs that which part of the examples failed or is missing something, and the `json_path` is the jsonpath in which we have to replace the specific document part in the big base document itself. and the specified path should be checked, if it exists replace it there, otherwise create the field which is missing using the jsonpath + +we will use the asyncapi cli to validate the updated document generated by the script +Now we need that the new updated document which is created by the script is passed and validated by the cli tool and after validation is deleted, this should be done in the runtime itself and we don't want any extra document to be present after the whole process diff --git a/scripts/validation/embedded-files-test/updated-doc.json b/scripts/validation/embedded-files-test/updated-doc.json new file mode 100644 index 00000000..848f70e3 --- /dev/null +++ b/scripts/validation/embedded-files-test/updated-doc.json @@ -0,0 +1,600 @@ +{ + "asyncapi": "3.0.0", + "info": { + "title": "AsyncAPI Sample App", + "version": "1.0.1", + "description": "This is a sample app.", + "termsOfService": "https://asyncapi.org/terms/", + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + }, + "externalDocs": { + "description": "Find more info here", + "url": "https://www.asyncapi.org" + }, + "tags": [ + { + "name": "e-commerce" + } + ], + "contact": { + "name": "API Support", + "url": "https://www.asyncapi.org/support", + "email": "support@asyncapi.org" + } + }, + "servers": { + "production": { + "host": "rabbitmq.in.mycompany.com:5672", + "pathname": "/v1", + "protocol": "amqp", + "protocolVersion": "1.0", + "description": "Production RabbitMQ broker (uses the `production` vhost).", + "title": "Production Server", + "summary": "Production environment server", + "security": [ + { + "type": "http", + "scheme": "bearer" + } + ], + "tags": [ + { + "name": "production", + "description": "Production environment" + } + ], + "externalDocs": { + "description": "Additional documentation for the production server", + "url": "https://example.com/docs/production" + }, + "bindings": { + "amqp": { + "exchange": "my-exchange", + "queue": "my-queue" + } + } + }, + "staging": { + "host": "rabbitmq.in.mycompany.com:5672", + "pathname": "/v1", + "protocol": "amqp", + "protocolVersion": "1.0", + "description": "Staging RabbitMQ broker (uses the `staging` vhost).", + "title": "Staging Server", + "summary": "Staging environment server", + "security": [ + { + "type": "apiKey", + "in": "user", + "description": "Provide your API key as the user and leave the password empty." + } + ], + "tags": [ + { + "name": "staging", + "description": "Staging environment" + } + ], + "externalDocs": { + "description": "Additional documentation for the staging server", + "url": "https://example.com/docs/staging" + }, + "bindings": { + "amqp": { + "exchange": "my-exchange", + "queue": "my-queue" + } + } + } + }, + "channels": { + "user": { + "address": "users.{userId}", + "title": "Users channel", + "description": "This channel is used to exchange messages about user events.", + "messages": { + "userSignedUp": { + "$ref": "#/components/messages/userSignedUp" + }, + "userCompletedOrder": { + "$ref": "#/components/messages/userCompletedOrder" + } + }, + "parameters": { + "userId": { + "$ref": "#/components/parameters/userId" + } + }, + "servers": [ + { + "$ref": "#/servers/production" + } + ], + "bindings": { + "amqp": { + "is": "queue", + "queue": { + "exclusive": true + } + } + }, + "tags": [ + { + "name": "user", + "description": "User-related messages" + } + ], + "externalDocs": { + "description": "Find more info here", + "url": "https://example.com" + } + }, + "userSignupReply": { + "address": "users.signup.reply", + "description": "Channel for user signup replies", + "messages": { + "userSignedUpReply": { + "summary": "User signup reply message", + "payload": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "Status of the signup process" + }, + "message": { + "type": "string", + "description": "Additional information" + } + } + } + } + } + } + }, + "operations": { + "sendUserSignUp": { + "action": "send", + "title": "User sign up", + "summary": "Action to sign a user up.", + "description": "A longer description", + "channel": { + "$ref": "#/channels/userSignup" + }, + "security": [ + { + "type": "oauth2", + "description": "The oauth security descriptions", + "flows": { + "clientCredentials": { + "tokenUrl": "https://example.com/api/oauth/dialog", + "availableScopes": { + "subscribe:auth_revocations": "Scope required for authorization revocation topic" + } + } + }, + "scopes": [ + "subscribe:auth_revocations" + ], + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ], + "tags": [ + { + "name": "user" + }, + { + "name": "signup" + }, + { + "name": "register" + } + ], + "bindings": { + "amqp": { + "ack": false + } + }, + "messages": [ + { + "$ref": "/components/messages/userSignedUp" + } + ], + "reply": { + "address": { + "location": "$message.header#/replyTo" + }, + "channel": { + "$ref": "#/channels/userSignupReply" + }, + "messages": [ + { + "$ref": "/components/messages/userSignedUpReply" + } + ] + }, + "traits": [ + { + "$ref": "#/components/operationTraits/kafka" + } + ] + } + }, + "components": { + "schemas": { + "Category": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + } + } + }, + "AvroExample": { + "schemaFormat": "application/vnd.apache.avro+json;version=1.9.0", + "schema": { + "type": "record", + "name": "UserCreate", + "namespace": "com.example", + "fields": [ + { + "name": "id", + "type": "int" + }, + { + "name": "name", + "type": "string" + } + ] + } + }, + "userCreate": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The ID of the user" + }, + "name": { + "type": "string", + "description": "The name of the user" + }, + "email": { + "type": "string", + "format": "email", + "description": "The email of the user" + } + }, + "required": [ + "id", + "name", + "email" + ] + }, + "signup": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "format": "date-time", + "description": "The timestamp of the signup" + }, + "source": { + "type": "string", + "description": "The source of the signup" + } + }, + "required": [ + "timestamp", + "source" + ] + } + }, + "servers": { + "development": { + "host": "{stage}.in.mycompany.com", + "protocol": "amqp", + "description": "RabbitMQ broker", + "bindings": { + "$ref": "#/components/serverBindings/devAmqp" + }, + "variables": { + "stage": { + "$ref": "#/components/serverVariables/stage" + } + }, + "security": [ + { + "$ref": "#/components/securitySchemes/oauth" + } + ] + } + }, + "serverVariables": { + "stage": { + "default": "demo", + "description": "This value is assigned by the service provider in this example of `mycompany.com`" + } + }, + "channels": { + "user": { + "address": "users.{userId}", + "title": "Users channel", + "description": "This channel is used to exchange messages about user events.", + "messages": { + "userSignedUp": { + "$ref": "#/components/messages/userSignUp" + } + }, + "parameters": { + "userId": { + "$ref": "#/components/parameters/userId" + } + }, + "servers": [ + { + "$ref": "#/components/servers/development" + } + ], + "bindings": { + "$ref": "#/components/channelBindings/user" + }, + "tags": [ + { + "$ref": "#/components/tags/user" + } + ], + "externalDocs": { + "$ref": "#/components/externalDocs/infoDocs" + } + } + }, + "messages": { + "userSignUp": { + "summary": "Action to sign a user up.", + "traits": [ + { + "$ref": "#/components/messageTraits/commonHeaders" + } + ], + "payload": { + "$ref": "#/components/schemas/Category" + }, + "correlationId": { + "$ref": "#/components/correlationIds/default" + }, + "bindings": { + "$ref": "#/components/messageBindings/user" + } + }, + "userSignedUp": { + "name": "UserSignup", + "title": "User signup", + "summary": "Action to sign a user up.", + "description": "A longer description", + "contentType": "application/json", + "tags": [ + { + "name": "user" + }, + { + "name": "signup" + }, + { + "name": "register" + } + ], + "headers": { + "type": "object", + "properties": { + "correlationId": { + "description": "Correlation ID set by application", + "type": "string" + }, + "applicationInstanceId": { + "description": "Unique identifier for a given instance of the publishing application", + "type": "string" + } + } + }, + "payload": { + "type": "object", + "properties": { + "user": { + "$ref": "#/components/schemas/userCreate" + }, + "signup": { + "$ref": "#/components/schemas/signup" + } + } + }, + "correlationId": { + "description": "Default Correlation ID", + "location": "$message.header#/correlationId" + }, + "traits": [ + { + "$ref": "#/components/messageTraits/commonHeaders" + } + ], + "examples": [ + { + "name": "SimpleSignup", + "summary": "A simple UserSignup example message", + "headers": { + "correlationId": "my-correlation-id", + "applicationInstanceId": "myInstanceId" + }, + "payload": { + "user": { + "someUserKey": "someUserValue" + }, + "signup": { + "someSignupKey": "someSignupValue" + } + } + } + ] + }, + "userCompletedOrder": { + "summary": "User completed order event", + "contentType": "application/json", + "payload": { + "type": "object", + "properties": { + "orderId": { + "type": "string", + "description": "The ID of the order" + }, + "userId": { + "type": "string", + "description": "The ID of the user" + }, + "amount": { + "type": "number", + "description": "The total amount of the order" + } + } + } + } + }, + "parameters": { + "userId": { + "description": "Id of the user." + } + }, + "correlationIds": { + "default": { + "description": "Default Correlation ID", + "location": "$message.header#/correlationId" + } + }, + "operations": { + "sendUserSignUp": { + "action": "send", + "title": "User sign up", + "channel": { + "$ref": "#/channels/user" + }, + "bindings": { + "$ref": "#/components/operationBindings/sendUser" + }, + "traits": [ + { + "$ref": "#/components/operationTraits/binding" + } + ], + "reply": { + "$ref": "#/components/replies/signupReply" + } + } + }, + "replies": { + "signupReply": { + "address": { + "$ref": "#/components/replyAddresses/signupReply" + }, + "channel": { + "$ref": "#/channels/userSignupReply" + } + } + }, + "replyAddresses": { + "signupReply": { + "location": "$message.header#/replyTo" + } + }, + "securitySchemes": { + "oauth": { + "type": "oauth2", + "description": "The oauth security descriptions", + "flows": { + "clientCredentials": { + "tokenUrl": "https://example.com/api/oauth/dialog", + "availableScopes": { + "subscribe:auth_revocations": "Scope required for authorization revocation topic" + } + } + }, + "scopes": [ + "subscribe:auth_revocations" + ] + } + }, + "operationTraits": { + "binding": { + "bindings": { + "amqp": { + "ack": false + } + } + } + }, + "messageTraits": { + "commonHeaders": { + "headers": { + "type": "object", + "properties": { + "my-app-header": { + "type": "integer", + "minimum": 0, + "maximum": 100 + } + } + } + } + }, + "tags": { + "user": { + "name": "user", + "description": "User-related messages" + } + }, + "externalDocs": { + "infoDocs": { + "url": "https://example.com/docs", + "description": "Find more info here" + } + }, + "serverBindings": { + "devAmqp": { + "amqp": { + "exchange": "my-exchange", + "queue": "my-queue" + } + } + }, + "channelBindings": { + "user": { + "amqp": { + "is": "queue", + "queue": { + "exclusive": true + } + } + } + }, + "operationBindings": { + "sendUser": { + "amqp": { + "ack": false + } + } + }, + "messageBindings": { + "user": { + "amqp": { + "contentEncoding": "gzip", + "messageType": "user.signup", + "bindingVersion": "0.3.0" + } + } + } + } +} \ No newline at end of file diff --git a/scripts/validation/package-lock.json b/scripts/validation/package-lock.json new file mode 100644 index 00000000..2f2143b7 --- /dev/null +++ b/scripts/validation/package-lock.json @@ -0,0 +1,1921 @@ +{ + "name": "validation", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "validation", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@asyncapi/parser": "^3.0.14", + "js-yaml": "^4.1.0", + "jsonpath-plus": "^9.0.0", + "marked": "^12.0.2" + } + }, + "node_modules/@asyncapi/parser": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@asyncapi/parser/-/parser-3.0.14.tgz", + "integrity": "sha512-tC2gmKkw28PWWMcGUXHQjTfVftiZdr+FQtsfapaHh36spX9uwe13iYzkcTyCkwSJAHibtg7wvStuHsiufP8xng==", + "dev": true, + "dependencies": { + "@asyncapi/specs": "^6.6.0", + "@openapi-contrib/openapi-schema-to-json-schema": "~3.2.0", + "@stoplight/json": "^3.20.2", + "@stoplight/json-ref-readers": "^1.2.2", + "@stoplight/json-ref-resolver": "^3.1.5", + "@stoplight/spectral-core": "^1.16.1", + "@stoplight/spectral-functions": "^1.7.2", + "@stoplight/spectral-parsers": "^1.0.2", + "@stoplight/spectral-ref-resolver": "^1.0.3", + "@stoplight/types": "^13.12.0", + "@types/json-schema": "^7.0.11", + "@types/urijs": "^1.19.19", + "ajv": "^8.11.0", + "ajv-errors": "^3.0.0", + "ajv-formats": "^2.1.1", + "avsc": "^5.7.5", + "js-yaml": "^4.1.0", + "jsonpath-plus": "^7.2.0", + "node-fetch": "2.6.7" + } + }, + "node_modules/@asyncapi/parser/node_modules/jsonpath-plus": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", + "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@asyncapi/specs": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-6.7.1.tgz", + "integrity": "sha512-jEaW2vgAwD9GboCdO/TI1zN2k+iowL8YFYwiZwTIr4U4KDmsgo3BLypScl6Jl4+IvY9RdsWE67nuzVX7jooiqQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.11" + } + }, + "node_modules/@jsep-plugin/assignment": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.2.1.tgz", + "integrity": "sha512-gaHqbubTi29aZpVbBlECRpmdia+L5/lh2BwtIJTmtxdbecEyyX/ejAOg7eQDGNvGOUmPY7Z2Yxdy9ioyH/VJeA==", + "dev": true, + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@jsep-plugin/regex": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", + "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", + "dev": true, + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@jsep-plugin/ternary": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/ternary/-/ternary-1.1.3.tgz", + "integrity": "sha512-qtLGzCNzPVJ3kdH6/zoLWDPjauHIKiLSBAR71Wa0+PWvGA8wODUQvRgxtpUA5YqAYL3CQ8S4qXhd/9WuWTZirg==", + "dev": true, + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@openapi-contrib/openapi-schema-to-json-schema": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@openapi-contrib/openapi-schema-to-json-schema/-/openapi-schema-to-json-schema-3.2.0.tgz", + "integrity": "sha512-Gj6C0JwCr8arj0sYuslWXUBSP/KnUlEGnPW4qxlXvAl543oaNQgMgIgkQUA6vs5BCCvwTEiL8m/wdWzfl4UvSw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + } + }, + "node_modules/@stoplight/better-ajv-errors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz", + "integrity": "sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==", + "dev": true, + "dependencies": { + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": "^12.20 || >= 14.13" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/@stoplight/json": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.21.0.tgz", + "integrity": "sha512-5O0apqJ/t4sIevXCO3SBN9AHCEKKR/Zb4gaj7wYe5863jme9g02Q0n/GhM7ZCALkL+vGPTe4ZzTETP8TFtsw3g==", + "dev": true, + "dependencies": { + "@stoplight/ordered-object-literal": "^1.0.3", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^13.6.0", + "jsonc-parser": "~2.2.1", + "lodash": "^4.17.21", + "safe-stable-stringify": "^1.1" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/@stoplight/json-ref-readers": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@stoplight/json-ref-readers/-/json-ref-readers-1.2.2.tgz", + "integrity": "sha512-nty0tHUq2f1IKuFYsLM4CXLZGHdMn+X/IwEUIpeSOXt0QjMUbL0Em57iJUDzz+2MkWG83smIigNZ3fauGjqgdQ==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.0", + "tslib": "^1.14.1" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/@stoplight/json-ref-resolver": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@stoplight/json-ref-resolver/-/json-ref-resolver-3.1.6.tgz", + "integrity": "sha512-YNcWv3R3n3U6iQYBsFOiWSuRGE5su1tJSiX6pAPRVk7dP0L7lqCteXGzuVRQ0gMZqUl8v1P0+fAKxF6PLo9B5A==", + "dev": true, + "dependencies": { + "@stoplight/json": "^3.21.0", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^12.3.0 || ^13.0.0", + "@types/urijs": "^1.19.19", + "dependency-graph": "~0.11.0", + "fast-memoize": "^2.5.2", + "immer": "^9.0.6", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "urijs": "^1.19.11" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/@stoplight/json-ref-resolver/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/@stoplight/ordered-object-literal": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.5.tgz", + "integrity": "sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@stoplight/path": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@stoplight/path/-/path-1.3.2.tgz", + "integrity": "sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@stoplight/spectral-core": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.18.3.tgz", + "integrity": "sha512-YY8x7X2SWJIhGTLPol+eFiQpWPz0D0mJdkK2i4A0QJG68KkNhypP6+JBC7/Kz3XWjqr0L/RqAd+N5cQLPOKZGQ==", + "dev": true, + "dependencies": { + "@stoplight/better-ajv-errors": "1.0.3", + "@stoplight/json": "~3.21.0", + "@stoplight/path": "1.3.2", + "@stoplight/spectral-parsers": "^1.0.0", + "@stoplight/spectral-ref-resolver": "^1.0.0", + "@stoplight/spectral-runtime": "^1.0.0", + "@stoplight/types": "~13.6.0", + "@types/es-aggregate-error": "^1.0.2", + "@types/json-schema": "^7.0.11", + "ajv": "^8.6.0", + "ajv-errors": "~3.0.0", + "ajv-formats": "~2.1.0", + "es-aggregate-error": "^1.0.7", + "jsonpath-plus": "7.1.0", + "lodash": "~4.17.21", + "lodash.topath": "^4.5.2", + "minimatch": "3.1.2", + "nimma": "0.2.2", + "pony-cause": "^1.0.0", + "simple-eval": "1.0.0", + "tslib": "^2.3.0" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/@stoplight/spectral-core/node_modules/@stoplight/types": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, + "node_modules/@stoplight/spectral-core/node_modules/jsonpath-plus": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.1.0.tgz", + "integrity": "sha512-gTaNRsPWO/K2KY6MrqaUFClF9kmuM6MFH5Dhg1VYDODgFbByw1yb7xu3hrViE/sz+dGOeMWgCzwUwQtAnCTE9g==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@stoplight/spectral-core/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/@stoplight/spectral-formats": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.6.0.tgz", + "integrity": "sha512-X27qhUfNluiduH0u/QwJqhOd8Wk5YKdxVmKM03Aijlx0AH1H5mYt3l9r7t2L4iyJrsBaFPnMGt7UYJDGxszbNA==", + "dev": true, + "dependencies": { + "@stoplight/json": "^3.17.0", + "@stoplight/spectral-core": "^1.8.0", + "@types/json-schema": "^7.0.7", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stoplight/spectral-formats/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/@stoplight/spectral-functions": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.2.tgz", + "integrity": "sha512-f+61/FtIkQeIo+a269CeaeqjpyRsgDyIk6DGr7iS4hyuk1PPk7Uf6MNRDs9FEIBh7CpdEJ+HSHbMLwgpymWTIw==", + "dev": true, + "dependencies": { + "@stoplight/better-ajv-errors": "1.0.3", + "@stoplight/json": "^3.17.1", + "@stoplight/spectral-core": "^1.7.0", + "@stoplight/spectral-formats": "^1.0.0", + "@stoplight/spectral-runtime": "^1.1.0", + "ajv": "^8.6.3", + "ajv-draft-04": "~1.0.0", + "ajv-errors": "~3.0.0", + "ajv-formats": "~2.1.0", + "lodash": "~4.17.21", + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stoplight/spectral-functions/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/@stoplight/spectral-parsers": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.4.tgz", + "integrity": "sha512-nCTVvtX6q71M8o5Uvv9kxU31Gk1TRmgD6/k8HBhdCmKG6FWcwgjiZouA/R3xHLn/VwTI/9k8SdG5Mkdy0RBqbQ==", + "dev": true, + "dependencies": { + "@stoplight/json": "~3.21.0", + "@stoplight/types": "^14.1.1", + "@stoplight/yaml": "~4.3.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, + "node_modules/@stoplight/spectral-parsers/node_modules/@stoplight/types": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-14.1.1.tgz", + "integrity": "sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, + "node_modules/@stoplight/spectral-parsers/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/@stoplight/spectral-ref-resolver": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-ref-resolver/-/spectral-ref-resolver-1.0.4.tgz", + "integrity": "sha512-5baQIYL0NJTSVy8v6RxOR4U51xOUYM8wJri1YvlAT6bPN8m0EIxMwfVYi0xUZEMVeHcWx869nIkoqyWmOutF2A==", + "dev": true, + "dependencies": { + "@stoplight/json-ref-readers": "1.2.2", + "@stoplight/json-ref-resolver": "~3.1.6", + "@stoplight/spectral-runtime": "^1.1.2", + "dependency-graph": "0.11.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stoplight/spectral-ref-resolver/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/@stoplight/spectral-runtime": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-runtime/-/spectral-runtime-1.1.2.tgz", + "integrity": "sha512-fr5zRceXI+hrl82yAVoME+4GvJie8v3wmOe9tU+ZLRRNonizthy8qDi0Z/z4olE+vGreSDcuDOZ7JjRxFW5kTw==", + "dev": true, + "dependencies": { + "@stoplight/json": "^3.17.0", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^12.3.0", + "abort-controller": "^3.0.0", + "lodash": "^4.17.21", + "node-fetch": "^2.6.7", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stoplight/spectral-runtime/node_modules/@stoplight/types": { + "version": "12.5.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-12.5.0.tgz", + "integrity": "sha512-dwqYcDrGmEyUv5TWrDam5TGOxU72ufyQ7hnOIIDdmW5ezOwZaBFoR5XQ9AsH49w7wgvOqB2Bmo799pJPWnpCbg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@stoplight/spectral-runtime/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/@stoplight/types": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.20.0.tgz", + "integrity": "sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, + "node_modules/@stoplight/yaml": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.3.0.tgz", + "integrity": "sha512-JZlVFE6/dYpP9tQmV0/ADfn32L9uFarHWxfcRhReKUnljz1ZiUM5zpX+PH8h5CJs6lao3TuFqnPm9IJJCEkE2w==", + "dev": true, + "dependencies": { + "@stoplight/ordered-object-literal": "^1.0.5", + "@stoplight/types": "^14.1.1", + "@stoplight/yaml-ast-parser": "0.0.50", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=10.8" + } + }, + "node_modules/@stoplight/yaml-ast-parser": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.50.tgz", + "integrity": "sha512-Pb6M8TDO9DtSVla9yXSTAxmo9GVEouq5P40DWXdOie69bXogZTkgvopCq+yEvTMA0F6PEvdJmbtTV3ccIp11VQ==", + "dev": true + }, + "node_modules/@stoplight/yaml/node_modules/@stoplight/types": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-14.1.1.tgz", + "integrity": "sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, + "node_modules/@stoplight/yaml/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/@types/es-aggregate-error": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.6.tgz", + "integrity": "sha512-qJ7LIFp06h1QE1aVxbVd+zJP2wdaugYXYfd6JxsyRMrYHaxb6itXPogW2tz+ylUJ1n1b+JF1PHyYCfYHm0dvUg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.12.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.13.tgz", + "integrity": "sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/urijs": { + "version": "1.19.25", + "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.25.tgz", + "integrity": "sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==", + "dev": true + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/ajv": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.14.0.tgz", + "integrity": "sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", + "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", + "dev": true, + "peerDependencies": { + "ajv": "^8.0.1" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/astring": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", + "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "dev": true, + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/avsc": { + "version": "5.7.7", + "resolved": "https://registry.npmjs.org/avsc/-/avsc-5.7.7.tgz", + "integrity": "sha512-9cYNccliXZDByFsFliVwk5GvTq058Fj513CiR4E60ndDwmuXzTJEp/Bp8FyuRmGyYupLjHLs+JA9/CBoVS4/NQ==", + "dev": true, + "engines": { + "node": ">=0.11" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-aggregate-error": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/es-aggregate-error/-/es-aggregate-error-1.0.13.tgz", + "integrity": "sha512-KkzhUUuD2CUMqEc8JEqsXEMDHzDPE8RCjZeUBitsnB1eNcAJWQPiciKsMXe3Yytj4Flw1XLl46Qcf9OxvZha7A==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-memoize": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", + "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsep": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.8.tgz", + "integrity": "sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ==", + "dev": true, + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/jsonc-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", + "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==", + "dev": true + }, + "node_modules/jsonpath-plus": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-9.0.0.tgz", + "integrity": "sha512-bqE77VIDStrOTV/czspZhTn+o27Xx9ZJRGVkdVShEtPoqsIx5yALv3lWVU6y+PqYvWPJNWE7ORCQheQkEe0DDA==", + "dev": true, + "dependencies": { + "@jsep-plugin/assignment": "^1.2.1", + "@jsep-plugin/regex": "^1.0.3", + "jsep": "^1.3.8" + }, + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.topath": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", + "integrity": "sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==", + "dev": true + }, + "node_modules/marked": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", + "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nimma": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/nimma/-/nimma-0.2.2.tgz", + "integrity": "sha512-V52MLl7BU+tH2Np9tDrIXK8bql3MVUadnMIl/0/oZSGC9keuro0O9UUv9QKp0aMvtN8HRew4G7byY7H4eWsxaQ==", + "dev": true, + "dependencies": { + "@jsep-plugin/regex": "^1.0.1", + "@jsep-plugin/ternary": "^1.0.2", + "astring": "^1.8.1", + "jsep": "^1.2.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + }, + "optionalDependencies": { + "jsonpath-plus": "^6.0.1", + "lodash.topath": "^4.5.2" + } + }, + "node_modules/nimma/node_modules/jsonpath-plus": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-6.0.1.tgz", + "integrity": "sha512-EvGovdvau6FyLexFH2OeXfIITlgIbgZoAZe3usiySeaIDm5QS+A10DKNpaPBBqqRSZr2HN6HVNXxtwUAr2apEw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/pony-cause": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pony-cause/-/pony-cause-1.1.1.tgz", + "integrity": "sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", + "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-eval": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-eval/-/simple-eval-1.0.0.tgz", + "integrity": "sha512-kpKJR+bqTscgC0xuAl2xHN6bB12lHjC2DCUfqjAx19bQyO3R2EVLOurm3H9AUltv/uFVcSCVNc6faegR+8NYLw==", + "dev": true, + "dependencies": { + "jsep": "^1.1.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urijs": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", + "dev": true + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + } + } +} diff --git a/scripts/validation/package.json b/scripts/validation/package.json new file mode 100644 index 00000000..54676696 --- /dev/null +++ b/scripts/validation/package.json @@ -0,0 +1,17 @@ +{ + "name": "validation", + "version": "1.0.0", + "description": "for example validation files", + "main": "validate-embedded-examples.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Animesh Kumar", + "license": "ISC", + "devDependencies": { + "@asyncapi/parser": "^3.0.14", + "js-yaml": "^4.1.0", + "jsonpath-plus": "^9.0.0", + "marked": "^12.0.2" + } +} diff --git a/scripts/validation/script-v1.js b/scripts/validation/script-v1.js new file mode 100644 index 00000000..f606807f --- /dev/null +++ b/scripts/validation/script-v1.js @@ -0,0 +1,68 @@ +const fs = require('fs'); +const path = require('path'); +const yaml = require('js-yaml'); +const { execSync } = require('child_process'); + +// Path to the Markdown file +// const mdPath = './test-document.md'; +const mdPath = '../../spec/asyncapi.md'; + +// Function to create a full AsyncAPI document from an example +function createFullDocument(example) { + return { + asyncapi: '3.0.0', + info: { + title: 'Sample Document', + version: '0.0.0' + }, + ...example + }; +} + +// Extract AsyncAPI YAML snippets from the markdown file +function extractAsyncAPISnippets(mdContent) { + const snippets = []; + const codeBlockRegex = /```yaml([^```]+)```/g; + let match; + + while ((match = codeBlockRegex.exec(mdContent)) !== null) { + const yamlContent = match[1].trim(); + try { + const parsedYaml = yaml.load(yamlContent); + snippets.push(parsedYaml); + } catch (error) { + console.error('Failed to parse YAML:', error); + } + } + + return snippets; +} + +// Save each full document as a temporary file and validate using AsyncAPI CLI +async function validateExamples(mdPath) { + const mdContent = fs.readFileSync(mdPath, 'utf8'); + const snippets = extractAsyncAPISnippets(mdContent); + const tempDir = fs.mkdtempSync(path.join(__dirname, 'temp-')); + + try { + for (const [index, snippet] of snippets.entries()) { + const fullDoc = createFullDocument(snippet); + const tempFilePath = path.join(tempDir, `snippet-${index + 1}.yaml`); + fs.writeFileSync(tempFilePath, yaml.dump(fullDoc)); + + try { + execSync(`npx asyncapi validate ${tempFilePath}`, { stdio: 'inherit' }); + console.log(`\nValidation successful for: ${tempFilePath}`); + } catch (error) { + console.error(`Validation failed for: ${tempFilePath}`); + } + } + } finally { + // fs.rmSync(tempDir, { recursive: true, force: true }); + } +} + +validateExamples(mdPath).catch((error) => { + console.error('Validation script failed:', error); + process.exit(1); // Exit with an error code to fail the CI job + }); \ No newline at end of file diff --git a/scripts/validation/script-v2.js b/scripts/validation/script-v2.js new file mode 100644 index 00000000..61a74e6a --- /dev/null +++ b/scripts/validation/script-v2.js @@ -0,0 +1,91 @@ +const fs = require('fs'); +const path = require('path'); +const yaml = require('js-yaml'); +const { execSync } = require('child_process'); + +// Path to the Markdown file +const mdPath = process.env.MARKDOWN_PATH || '../../spec/asyncapi.md'; + +// Function to create a full AsyncAPI document from an example +function createFullDocument(example) { + return { + asyncapi: '3.0.0', + info: { + title: 'Sample Document', + version: '0.0.0' + }, + ...example + }; +} + +// Extract AsyncAPI YAML snippets from the markdown file and track their line numbers +function extractAsyncAPISnippetsWithLineNumbers(mdContent) { + const snippets = []; + const lines = mdContent.split('\n'); + const codeBlockStartRegex = /^```yaml$/; + const codeBlockEndRegex = /^```$/; + let inCodeBlock = false; + let codeBlockStart = null; + let codeLines = []; + + lines.forEach((line, index) => { + if (codeBlockStartRegex.test(line.trim())) { + inCodeBlock = true; + codeBlockStart = index; + } else if (inCodeBlock && codeBlockEndRegex.test(line.trim())) { + inCodeBlock = false; + const yamlContent = codeLines.join('\n').trim(); + try { + const parsedYaml = yaml.load(yamlContent); + snippets.push({ + content: parsedYaml, + startLine: codeBlockStart + 1, + endLine: index + 1 + }); + } catch (error) { + console.error(`Failed to parse YAML from lines ${codeBlockStart + 1}-${index + 1}:`, error); + } + codeLines = []; + } else if (inCodeBlock) { + codeLines.push(line); + } + }); + + return snippets; +} + +// Save each full document as a temporary file and validate using AsyncAPI CLI +async function validateExamples(mdPath) { + const mdContent = fs.readFileSync(mdPath, 'utf8'); + const snippets = extractAsyncAPISnippetsWithLineNumbers(mdContent); + const tempDir = fs.mkdtempSync(path.join(__dirname, 'temp-')); + + let allValid = true; + + try { + for (const [index, snippet] of snippets.entries()) { + const fullDoc = createFullDocument(snippet.content); + const tempFilePath = path.join(tempDir, `snippet-${index + 1}.yaml`); + fs.writeFileSync(tempFilePath, yaml.dump(fullDoc)); + + try { + execSync(`npx asyncapi validate ${tempFilePath}`, { stdio: 'inherit' }); + console.log(`\nValidation successful for snippet from lines ${snippet.startLine} to ${snippet.endLine}`); + } catch (error) { + console.error(`Validation failed for snippet from lines ${snippet.startLine} to ${snippet.endLine}`); + allValid = false; + } + } + } finally { + fs.rmSync(tempDir, { recursive: true, force: true }); + } + + if (!allValid) { + process.exit(1); // Exit with an error code if any validation failed + } +} + +validateExamples(mdPath).catch((error) => { + console.error('Validation script failed:', error); + process.exit(1); // Exit with an error code to fail the CI job +}); diff --git a/scripts/validation/test-02.json b/scripts/validation/test-02.json new file mode 100644 index 00000000..4c85deaf --- /dev/null +++ b/scripts/validation/test-02.json @@ -0,0 +1,68 @@ +{ + "asyncapi": "3.0.0", + "info": { + "title": "Sample API", + "version": "1.0.0", + "description": "This is a sample AsyncAPI document." + }, + "servers": { + "production": { + "host": "production.example.com", + "protocol": "amqp" + } + }, + "channels": { + "user/signedup": { + "address": "user/signedup", + "messages": { + "subscribe.message": { + "contentType": "application/json", + "payload": { + "type": "object", + "properties": { + "userId": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + }, + "description": "This channel is used to send user signed up events." + } + }, + "operations": { + "user/signedup.subscribe": { + "action": "send", + "channel": { + "$ref": "#/channels/user~1signedup" + }, + "summary": "Subscribe to user signed up events.", + "messages": [ + { + "$ref": "#/channels/user~1signedup/messages/subscribe.message" + } + ] + } + }, + "components": { + "messages": { + "UserSignedUp": { + "contentType": "application/json", + "payload": { + "type": "object", + "properties": { + "userId": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/scripts/validation/test-document.md b/scripts/validation/test-document.md new file mode 100644 index 00000000..1e9a605e --- /dev/null +++ b/scripts/validation/test-document.md @@ -0,0 +1,22 @@ +```yaml +asyncapi: 3.0.0 +info: + title: sample document + version: 0.0.0 +channels: + example: + messages: + myMessage: + payload: + schemaFormat: 'application/vnd.apache.avro;version=1.9.0' + schema: + type: record + name: User + namespace: com.company + doc: User information + fields: + - name: displayName + type: string + - name: age + type: int +``` \ No newline at end of file diff --git a/scripts/validation/validate-embedded-examples.js b/scripts/validation/validate-embedded-examples.js new file mode 100644 index 00000000..c006a2d3 --- /dev/null +++ b/scripts/validation/validate-embedded-examples.js @@ -0,0 +1,62 @@ +const fs = require('fs'); +const yaml = require('js-yaml'); +const { parse } = require('@asyncapi/parser'); + +// Path to the Markdown file +const mdPath = '../../spec/asyncapi.md'; + +// Function to create a full AsyncAPI document from an example +function createFullDocument(example) { + return { + asyncapi: '3.0.0', + info: { + title: 'Sample Document', + version: '0.0.0' + }, + ...example + }; +} + +// Function to validate an example +async function validateExample(example, fileName) { + const fullDoc = createFullDocument(example); + + try { + await parse(yaml.dump(fullDoc)); + console.log(`Validation successful for: ${fileName}`); + } catch (error) { + console.error(`Validation failed for: ${fileName}`, error); + } +} + + +// Extract AsyncAPI YAML snippets from the markdown file +function extractAsyncAPISnippets(mdContent) { + const snippets = []; + const codeBlockRegex = /```yaml([^```]+)```/g; + let match; + + while ((match = codeBlockRegex.exec(mdContent)) !== null) { + const yamlContent = match[1].trim(); + try { + const parsedYaml = yaml.load(yamlContent); + snippets.push(parsedYaml); + } catch (error) { + console.error('Failed to parse YAML:', error); + } + } + + return snippets; +} + +// Read the markdown file and extract examples +async function extractAndValidateExamples(mdPath) { + const mdContent = fs.readFileSync(mdPath, 'utf8'); + const snippets = extractAsyncAPISnippets(mdContent); + + for (const [index, snippet] of snippets.entries()) { + await validateExample(snippet, `snippet-${index + 1}`); + } +} + +extractAndValidateExamples(mdPath).catch(console.error);