diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml new file mode 100644 index 00000000..ca6ed2bb --- /dev/null +++ b/.github/workflows/openapi.yml @@ -0,0 +1,85 @@ +name: OpenAPI + +on: pull_request + +permissions: + contents: read + +concurrency: + group: openapi-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + openapi: + runs-on: ubuntu-latest + + if: ${{ github.repository_owner != 'nextcloud-gmbh' }} + + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Get php version + id: versions + uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1 + + - name: Set up php + uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2 + with: + php-version: ${{ steps.versions.outputs.php-available }} + extensions: xml + coverage: none + ini-file: development + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Check Typescript OpenApi types + id: check_typescript_openapi + uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0 + with: + files: "src/types/openapi/openapi*.ts" + + - name: Read package.json node and npm engines version + if: steps.check_typescript_openapi.outputs.files_exists == 'true' + uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2 + id: node_versions + # Continue if no package.json + continue-on-error: true + with: + fallbackNode: '^20' + fallbackNpm: '^10' + + - name: Set up node ${{ steps.node_versions.outputs.nodeVersion }} + if: ${{ steps.node_versions.outputs.nodeVersion }} + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: ${{ steps.node_versions.outputs.nodeVersion }} + + - name: Set up npm ${{ steps.node_versions.outputs.npmVersion }} + if: ${{ steps.node_versions.outputs.nodeVersion }} + run: npm i -g npm@"${{ steps.node_versions.outputs.npmVersion }}" + + - name: Install dependencies & build + if: ${{ steps.node_versions.outputs.nodeVersion }} + env: + CYPRESS_INSTALL_BINARY: 0 + PUPPETEER_SKIP_DOWNLOAD: true + run: | + npm ci + + - name: Set up dependencies + run: composer i + + - name: Regenerate OpenAPI + run: composer run openapi + + - name: Check openapi*.json and typescript changes + run: | + bash -c "[[ ! \"`git status --porcelain `\" ]] || (echo 'Please run \"composer run openapi\" and commit the openapi*.json files and (if applicable) src/types/openapi/openapi*.ts, see the section \"Show changes on failure\" for details' && exit 1)" + + - name: Show changes on failure + if: failure() + run: | + git status + git --no-pager diff + exit 1 # make it red to grab attention diff --git a/.gitignore b/.gitignore index 0e7f975f..6aad6090 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ js/ .*.sw* node_modules .php*.cache -/composer.lock /vendor/ /tests/.phpunit*cache diff --git a/composer.json b/composer.json index fe51a0b4..c9d597aa 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "cs:fix": "php-cs-fixer fix", "psalm": "psalm.phar --no-cache", "test:unit": "phpunit --config tests/phpunit.xml", - "openapi": "generate-spec --verbose --allow-missing-docs --continue-on-error" + "openapi": "generate-spec --verbose" }, "repositories": [ { diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..3e0bfb26 --- /dev/null +++ b/composer.lock @@ -0,0 +1,2524 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "973a79ca7eed8906c0085fac94e38a3c", + "packages": [ + { + "name": "erusev/parsedown", + "version": "1.7.4", + "source": { + "type": "git", + "url": "https://github.com/erusev/parsedown.git", + "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3", + "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35" + }, + "type": "library", + "autoload": { + "psr-0": { + "Parsedown": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "description": "Parser for Markdown.", + "homepage": "http://parsedown.org", + "keywords": [ + "markdown", + "parser" + ], + "support": { + "issues": "https://github.com/erusev/parsedown/issues", + "source": "https://github.com/erusev/parsedown/tree/1.7.x" + }, + "time": "2019-12-30T22:54:17+00:00" + }, + { + "name": "phpoffice/math", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/Math.git", + "reference": "f0f8cad98624459c540cdd61d2a174d834471773" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/Math/zipball/f0f8cad98624459c540cdd61d2a174d834471773", + "reference": "f0f8cad98624459c540cdd61d2a174d834471773", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xml": "*", + "php": "^7.1|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.88 || ^1.0.0", + "phpunit/phpunit": "^7.0 || ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\Math\\": "src/Math/", + "Tests\\PhpOffice\\Math\\": "tests/Math/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Progi1984", + "homepage": "https://lefevre.dev" + } + ], + "description": "Math - Manipulate Math Formula", + "homepage": "https://phpoffice.github.io/Math/", + "keywords": [ + "MathML", + "officemathml", + "php" + ], + "support": { + "issues": "https://github.com/PHPOffice/Math/issues", + "source": "https://github.com/PHPOffice/Math/tree/0.1.0" + }, + "time": "2023-09-25T12:08:20+00:00" + }, + { + "name": "phpoffice/phpword", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PHPWord.git", + "reference": "e76b701ef538cb749641514fcbc31a68078550fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PHPWord/zipball/e76b701ef538cb749641514fcbc31a68078550fa", + "reference": "e76b701ef538cb749641514fcbc31a68078550fa", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-xml": "*", + "php": "^7.1|^8.0", + "phpoffice/math": "^0.1" + }, + "require-dev": { + "dompdf/dompdf": "^2.0", + "ext-gd": "*", + "ext-libxml": "*", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.3", + "mpdf/mpdf": "^8.1", + "phpmd/phpmd": "^2.13", + "phpstan/phpstan-phpunit": "@stable", + "phpunit/phpunit": ">=7.0", + "symfony/process": "^4.4 || ^5.0", + "tecnickcom/tcpdf": "^6.5" + }, + "suggest": { + "dompdf/dompdf": "Allows writing PDF", + "ext-gd2": "Allows adding images", + "ext-xmlwriter": "Allows writing OOXML and ODF", + "ext-xsl": "Allows applying XSL style sheet to headers, to main document part, and to footers of an OOXML template", + "ext-zip": "Allows writing OOXML and ODF" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpWord\\": "src/PhpWord" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Mark Baker" + }, + { + "name": "Gabriel Bull", + "email": "me@gabrielbull.com", + "homepage": "http://gabrielbull.com/" + }, + { + "name": "Franck Lefevre", + "homepage": "https://rootslabs.net/blog/" + }, + { + "name": "Ivan Lanin", + "homepage": "http://ivan.lanin.org" + }, + { + "name": "Roman Syroeshko", + "homepage": "http://ru.linkedin.com/pub/roman-syroeshko/34/a53/994/" + }, + { + "name": "Antoine de Troostembergh" + } + ], + "description": "PHPWord - A pure PHP library for reading and writing word processing documents (OOXML, ODF, RTF, HTML, PDF)", + "homepage": "https://phpoffice.github.io/PHPWord/", + "keywords": [ + "ISO IEC 29500", + "OOXML", + "Office Open XML", + "OpenDocument", + "OpenXML", + "PhpOffice", + "PhpWord", + "Rich Text Format", + "WordprocessingML", + "doc", + "docx", + "html", + "odf", + "odt", + "office", + "pdf", + "php", + "reader", + "rtf", + "template", + "template processor", + "word", + "writer" + ], + "support": { + "issues": "https://github.com/PHPOffice/PHPWord/issues", + "source": "https://github.com/PHPOffice/PHPWord/tree/1.2.0" + }, + "time": "2023-11-30T11:22:23+00:00" + } + ], + "packages-dev": [ + { + "name": "adhocore/cli", + "version": "v1.6.2", + "source": { + "type": "git", + "url": "https://github.com/adhocore/php-cli.git", + "reference": "34191315b0da20b9b4ecad783d91db992fa209a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/adhocore/php-cli/zipball/34191315b0da20b9b4ecad783d91db992fa209a4", + "reference": "34191315b0da20b9b4ecad783d91db992fa209a4", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ahc\\Cli\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jitendra Adhikari", + "email": "jiten.adhikary@gmail.com" + } + ], + "description": "Command line interface library for PHP", + "keywords": [ + "argument-parser", + "argv-parser", + "cli", + "cli-action", + "cli-app", + "cli-color", + "cli-option", + "cli-writer", + "command", + "console", + "console-app", + "php-cli", + "php8", + "stream-input", + "stream-output" + ], + "support": { + "issues": "https://github.com/adhocore/php-cli/issues", + "source": "https://github.com/adhocore/php-cli/tree/v1.6.2" + }, + "funding": [ + { + "url": "https://paypal.me/ji10", + "type": "custom" + }, + { + "url": "https://github.com/adhocore", + "type": "github" + } + ], + "time": "2024-01-22T22:37:23+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:23:10+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nextcloud/coding-standard", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/nextcloud/coding-standard.git", + "reference": "cf5f18d989ec62fb4cdc7fc92a36baf34b3d829e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud/coding-standard/zipball/cf5f18d989ec62fb4cdc7fc92a36baf34b3d829e", + "reference": "cf5f18d989ec62fb4cdc7fc92a36baf34b3d829e", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0", + "php-cs-fixer/shim": "^3.17" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nextcloud\\CodingStandard\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christoph Wurst", + "email": "christoph@winzerhof-wurst.at" + } + ], + "description": "Nextcloud coding standards for the php cs fixer", + "support": { + "issues": "https://github.com/nextcloud/coding-standard/issues", + "source": "https://github.com/nextcloud/coding-standard/tree/v1.2.1" + }, + "time": "2024-02-01T14:54:37+00:00" + }, + { + "name": "nextcloud/ocp", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/nextcloud-deps/ocp.git", + "reference": "b8ae36e3e98db74bafd3dc7360cc758572e939b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/b8ae36e3e98db74bafd3dc7360cc758572e939b0", + "reference": "b8ae36e3e98db74bafd3dc7360cc758572e939b0", + "shasum": "" + }, + "require": { + "php": "~8.0 || ~8.1 || ~8.2 || ~8.3", + "psr/clock": "^1.0", + "psr/container": "^2.0.2", + "psr/event-dispatcher": "^1.0", + "psr/log": "^1.1.4" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "30.0.0-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Christoph Wurst", + "email": "christoph@winzerhof-wurst.at" + } + ], + "description": "Composer package containing Nextcloud's public API (classes, interfaces)", + "support": { + "issues": "https://github.com/nextcloud-deps/ocp/issues", + "source": "https://github.com/nextcloud-deps/ocp/tree/master" + }, + "time": "2024-04-03T00:32:10+00:00" + }, + { + "name": "nextcloud/openapi-extractor", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/nextcloud/openapi-extractor.git", + "reference": "5379789c3207b81a5b71960c047cfbf50b5be0d6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud/openapi-extractor/zipball/5379789c3207b81a5b71960c047cfbf50b5be0d6", + "reference": "5379789c3207b81a5b71960c047cfbf50b5be0d6", + "shasum": "" + }, + "require": { + "adhocore/cli": "^v1.6", + "ext-simplexml": "*", + "nikic/php-parser": "^4.16", + "php": "^8.1", + "phpstan/phpdoc-parser": "^1.23" + }, + "require-dev": { + "nextcloud/coding-standard": "^1.1" + }, + "default-branch": true, + "bin": [ + "generate-spec", + "merge-specs" + ], + "type": "library", + "autoload": { + "psr-4": { + "OpenAPIExtractor\\": "src" + } + }, + "scripts": { + "lint": [ + "find . -name \\*.php -not -path './tests/*' -not -path './vendor/*' -not -path './build/*' -print0 | xargs -0 -n1 php -l && php -l generate-spec && php -l merge-specs" + ], + "cs:check": [ + "php-cs-fixer fix --dry-run --diff" + ], + "cs:fix": [ + "php-cs-fixer fix" + ], + "test:unit": [ + "cd tests && ../generate-spec" + ] + }, + "support": { + "source": "https://github.com/nextcloud/openapi-extractor/tree/main", + "issues": "https://github.com/nextcloud/openapi-extractor/issues" + }, + "time": "2024-03-28T15:07:16+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.19.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4e1b88d21c69391150ace211e9eaf05810858d0b", + "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.1" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.1" + }, + "time": "2024-03-17T08:10:35+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "php-cs-fixer/shim", + "version": "v3.52.1", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/shim.git", + "reference": "baec5a6d4b24bad4c930d39fde34b2b0c1c8cd94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/baec5a6d4b24bad4c930d39fde34b2b0c1c8cd94", + "reference": "baec5a6d4b24bad4c930d39fde34b2b0c1c8cd94", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "replace": { + "friendsofphp/php-cs-fixer": "self.version" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer", + "php-cs-fixer.phar" + ], + "type": "application", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz RumiƄski", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "support": { + "issues": "https://github.com/PHP-CS-Fixer/shim/issues", + "source": "https://github.com/PHP-CS-Fixer/shim/tree/v3.52.1" + }, + "time": "2024-03-19T21:03:12+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.27.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "86e4d5a4b036f8f0be1464522f4c6b584c452757" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/86e4d5a4b036f8f0be1464522f4c6b584c452757", + "reference": "86e4d5a4b036f8f0be1464522f4c6b584c452757", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.27.0" + }, + "time": "2024-03-21T13:14:53+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.31", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", + "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:37:42+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.6.18", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "32c2c2d6580b1d8ab3c10b1e9e4dc263cc69bb04" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/32c2c2d6580b1d8ab3c10b1e9e4dc263cc69bb04", + "reference": "32c2c2d6580b1d8ab3c10b1e9e4dc263cc69bb04", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1 || ^2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.28", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.5", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.2", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.6-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.18" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-03-21T12:07:32+00:00" + }, + { + "name": "psalm/phar", + "version": "5.23.1", + "source": { + "type": "git", + "url": "https://github.com/psalm/phar.git", + "reference": "07bb50acefdaf7b663087186f86d47542a9b1622" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psalm/phar/zipball/07bb50acefdaf7b663087186f86d47542a9b1622", + "reference": "07bb50acefdaf7b663087186f86d47542a9b1622", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "vimeo/psalm": "*" + }, + "bin": [ + "psalm.phar" + ], + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer-based Psalm Phar", + "support": { + "issues": "https://github.com/psalm/phar/issues", + "source": "https://github.com/psalm/phar/tree/5.23.1" + }, + "time": "2024-03-11T20:43:33+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:27:43+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:19:30+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:30:58+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:03:51+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:33:00+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:35:11+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:20:34+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:07:39+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-14T16:00:52+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:13:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "nextcloud/ocp": 20, + "nextcloud/openapi-extractor": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^8.1" + }, + "platform-dev": [], + "platform-overrides": { + "php": "8.1" + }, + "plugin-api-version": "2.3.0" +} diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..f1f8e138 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,5 @@ +# Assistant developer doc + +This documentation is about [integrating the assistant](./web-integration.md) in the frontend of other Nextcloud applications +and about using the [OCS API](./ocs-api.md) to support assistant features in your application or client. + diff --git a/docs/ocs-api.md b/docs/ocs-api.md new file mode 100644 index 00000000..4c9f3086 --- /dev/null +++ b/docs/ocs-api.md @@ -0,0 +1,12 @@ +# Using the assistant OCS API + +The assistant OCS API allows you to run/schedule tasks, get the task history, manage tasks etc... + +This API is documented with OpenAPI. You can view it with the [ocs_api_viewer app](https://apps.nextcloud.com/apps/ocs_api_viewer): +* install the ocs_api_viewer app +* install the assistant +* browse the ocs_api_viewer app +* select "assistant" in the left sidebar + +For the moment we have different endpoints for Text Processing, Speech to text and Image generation. This will be unified +in the near future. diff --git a/docs/web-integration.md b/docs/web-integration.md new file mode 100644 index 00000000..7adc0ab8 --- /dev/null +++ b/docs/web-integration.md @@ -0,0 +1,88 @@ +# Integrating the assistant + +This section is about integrating the assistant in Nextcloud's web frontend. + +The assistant can be used anywhere in Nextcloud's frontend. The assistant modal can be opened with or without initial input. +It can also be opened to see the result of a task. + +## Displaying a task result in the assistant + +There are 2 ways to display a task with the assistant. + +### Open the assistant modal + +If you get a task with the `/ocs/v2.php/apps/assistant/api/v1/task/TASK_ID` or `/ocs/v2.php/apps/assistant/api/v1/tasks` OCS endpoint, +you can display it in the assistant UI by using the `OCA.Assistant.openAssistantTask` helper function. +This function takes the task object as parameter. Calling it will open the assistant and load the task values +(task type, input and output) in the UI. + +### Browse the assistant task result page + +There is a standalone page to display results of a task: +`/apps/assistant/task/view/TASK_ID` +It has the exact same content as the assistant modal. + +## Run a task + +A helper function is exposed as `OCA.Assistant.openAssistantForm`. It opens the assistant modal. + +It accepts one parameter which is an object that can contain those keys: +* appId: [string, mandatory] app id of the app currently displayed +* identifier: [string, optional, default: ''] the task identifier (if the task is scheduled, this helps to identify the task when receiving the "task finished" event in the backend) +* taskType: [string, optional, default: last used task type] initially selected task type. It can be a text processing task type class or `speech-to-text` or `OCP\TextToImage\Task` +* input: [string, optional, default: ''] initial input prompt +* isInsideViewer: [boolean, optional, default: false] should be true if this function is called while the Viewer is displayed +* closeOnResult: [boolean, optional, default: false] If true, the modal will be closed after running a synchronous task and getting its result +* actionButtons: [array, optional, default: empty list] List of extra buttons to show in the assistant result form (only used if closeOnResult is false) + +This function returns a promise that resolves when the assistant is closed, which happens if: +* A task has been scheduled +* A task has run synchronously and we got results + +The promise can also be rejected if something wrong happens. + +The promise resolves with a task object which looks like: + +```javascript +{ + appId: 'text', + category: 1, // 0: text generation, 1: image generation, 2: speech-to-text + id: 310, // the assistant task ID + identifier: 'my custom identifier', + inputs: { prompt: 'give me a short summary of a simple settings section about GitHub' }, + ocpTaskId: 152, // the underlying OCP task ID + output: 'blabla', + status: 3, // 0: unknown, 1: scheduled, 2: running, 3: sucessful, 4: failed + taskType: 'OCP\\TextProcessing\\FreePromptTaskType', + timestamp: 1711545305, + userId: 'janedoe', +} +``` + +Complete example: +``` javascript +OCA.Assistant.openAssistantForm({ + appId: 'my_app_id', + identifier: 'my custom identifier', + taskType: 'OCP\\TextProcessing\\FreePromptTaskType', + input: 'count to 3', + actionButtons: [ + { + label: 'Label 1', + title: 'Title 1', + type: 'warning', + iconSvg: cogSvg, + onClick: (output) => { console.debug('first button clicked', output) }, + }, + { + label: 'Label 2', + title: 'Title 2', + onClick: (output) => { console.debug('second button clicked', output) }, + }, + ], +}).then(task => { + console.debug('assistant promise success', task) +}).catch(error => { + console.debug('assistant promise failure', error) +}) +``` diff --git a/lib/Capabilities.php b/lib/Capabilities.php index 4996685b..c2ecc80e 100644 --- a/lib/Capabilities.php +++ b/lib/Capabilities.php @@ -19,7 +19,12 @@ public function __construct( } /** - * @return array> + * @return array{ + * assistant: array{ + * version: string, + * enabled?: bool + * } + * } */ public function getCapabilities(): array { $appVersion = $this->appManager->getAppVersion(Application::APP_ID); diff --git a/lib/Controller/AssistantApiController.php b/lib/Controller/AssistantApiController.php index f15d4cbf..af05d348 100644 --- a/lib/Controller/AssistantApiController.php +++ b/lib/Controller/AssistantApiController.php @@ -34,7 +34,11 @@ public function __construct( /** * Get available task types * + * Get all available task types that the assistant can handle. + * * @return DataResponse}, array{}> + * + * 200: Available task types returned */ #[NoAdminRequired] #[NoCSRFRequired] @@ -47,8 +51,13 @@ public function getAvailableTaskTypes(): DataResponse { /** * Delete an assistant task * - * @param int $metaTaskId + * This will cancel the task if needed and then delete it from the server. + * + * @param int $metaTaskId ID of the task * @return DataResponse + * + * 200: Task deleted successfully + * 404: Task not found */ #[NoAdminRequired] #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['task_management'])] @@ -65,8 +74,15 @@ public function deleteTask(int $metaTaskId): DataResponse { } /** - * @param int $metaTaskId + * Cancel a task + * + * This endpoint will prevent a scheduled task to run by unscheduling it + * + * @param int $metaTaskId ID of the task * @return DataResponse + * + * 200: Task canceled successfully + * 404: Task not found */ #[NoAdminRequired] #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['task_management'])] @@ -85,7 +101,9 @@ public function cancelTask(int $metaTaskId): DataResponse { /** * Get an assistant task * - * @param int $metaTaskId + * Get one specific task. It has to be a task owned by the current user. + * + * @param int $metaTaskId ID of the task * @return DataResponse|DataResponse * * 200: Task has been found @@ -108,9 +126,14 @@ public function getAssistantTask(int $metaTaskId): DataResponse { /** * Get user's tasks * - * @param string|null $taskType - * @param int|null $category + * Get a list of assistant tasks for the current user. + * + * @param string|null $taskType Task type id. If null, tasks of all task types will be retrieved + * @param int|null $category Task category. If null, tasks of all categories will be retrieved * @return DataResponse}, array{}>|DataResponse + * + * 200: User tasks returned + * 404: No tasks found */ #[NoAdminRequired] #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['task_management'])] @@ -132,11 +155,16 @@ public function getUserTasks(?string $taskType = null, ?int $category = null): D /** * Run a text processing task * - * @param array $inputs - * @param string $type - * @param string $appId - * @param string $identifier + * This endpoint will run the task synchronously. + * + * @param array $inputs Input parameters + * @param string $type Task type id + * @param string $appId App id to be set in the created task + * @param string $identifier Identifier to be set in the created task * @return DataResponse|DataResponse + * + * 200: Task started successfully + * 400: Running task is not possible */ #[NoAdminRequired] #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['text_processing'])] @@ -158,11 +186,16 @@ public function runTextProcessingTask(string $type, array $inputs, string $appId /** * Schedule a text processing task * - * @param array $inputs - * @param string $type - * @param string $appId - * @param string $identifier + * This endpoint will schedule the task for it to run as soon as possible. + * + * @param array $inputs Input parameters + * @param string $type Task type id + * @param string $appId App id to be set in the created task + * @param string $identifier Identifier to be set in the created task * @return DataResponse|DataResponse + * + * 200: Task scheduled + * 400: Scheduling task is not possible */ #[NoAdminRequired] #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['text_processing'])] @@ -184,13 +217,18 @@ public function scheduleTextProcessingTask(string $type, array $inputs, string $ /** * Run or schedule a text processing task * - * If the task runs immediately or is schedule depends on the estimated runtime declared by the provider. + * This endpoint will either run or schedule the task. + * + * The choice between run or schedule depends on the estimated runtime declared by the actual provider that will process the task. * - * @param array $inputs - * @param string $type - * @param string $appId - * @param string $identifier + * @param array $inputs Input parameters + * @param string $type Task type id + * @param string $appId App id to be set in the created task + * @param string $identifier Identifier to be set in the created task * @return DataResponse|DataResponse + * + * 200: Task scheduled + * 400: Scheduling task is not possible */ #[NoAdminRequired] #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['text_processing'])] @@ -214,8 +252,11 @@ public function runOrScheduleTextProcessingTask(string $type, array $inputs, str * * Parse and extract text content of a file (if the file type is supported) * - * @param string $filePath + * @param string $filePath Path of the file to parse in the user's storage * @return DataResponse|DataResponse + * + * 200: Text parsed from file successfully + * 400: Parsing text from file is not possible */ #[NoAdminRequired] public function parseTextFromFile(string $filePath): DataResponse { diff --git a/lib/Controller/SpeechToTextApiController.php b/lib/Controller/SpeechToTextApiController.php index e555aec0..6abcbdda 100644 --- a/lib/Controller/SpeechToTextApiController.php +++ b/lib/Controller/SpeechToTextApiController.php @@ -24,12 +24,15 @@ use Exception; use InvalidArgumentException; +use OC\User\NoUserException; use OCA\Assistant\AppInfo\Application; +use OCA\Assistant\ResponseDefinitions; use OCA\Assistant\Service\SpeechToText\SpeechToTextService; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; +use OCP\Files\InvalidPathException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\IL10N; @@ -38,6 +41,9 @@ use Psr\Log\LoggerInterface; use RuntimeException; +/** + * @psalm-import-type AssistantTask from ResponseDefinitions + */ class SpeechToTextApiController extends OCSController { public function __construct( @@ -73,13 +79,23 @@ public function getTranscript(int $id): DataResponse { /** - * Run audio transcription of an uploaded file + * Transcribe uploaded audio file + * + * Schedule audio transcription of an uploaded file and return the created task. * - * @return DataResponse + * @param string $appId App id to be set in the created task + * @param string $identifier Identifier to be set in the created task + * @return DataResponse|DataResponse + * @throws InvalidPathException + * @throws NotFoundException * @throws NotPermittedException + * @throws \OCP\DB\Exception + * + * 200: Task started successfully + * 400: Starting task is not possible */ #[NoAdminRequired] - public function transcribeAudio(): DataResponse { + public function transcribeAudio(string $appId, string $identifier): DataResponse { $audioData = $this->request->getUploadedFile('audioData'); if ($audioData['error'] !== 0) { @@ -95,8 +111,10 @@ public function transcribeAudio(): DataResponse { } try { - $this->sttService->transcribeAudio($audioData['tmp_name'], $this->userId); - return new DataResponse(''); + $task = $this->sttService->transcribeAudio($audioData['tmp_name'], $this->userId, $appId, $identifier); + return new DataResponse([ + 'task' => $task->jsonSerializeCc(), + ]); } catch (RuntimeException $e) { $this->logger->error( 'Runtime exception: ' . $e->getMessage(), @@ -122,20 +140,33 @@ public function transcribeAudio(): DataResponse { } /** - * Run audio transcription of a user's file + * Transcribe file from user's storage + * + * Schedule audio transcription of a user's storage file and return the created task * * @param string $path Nextcloud file path - * @return DataResponse + * @param string $appId App id to be set in the created task + * @param string $identifier Identifier to be set in the created task + * @return DataResponse|DataResponse + * @throws InvalidPathException + * @throws NoUserException + * @throws \OCP\DB\Exception + * + * 200: Task started successfully + * 400: Starting task is not possible + * 404: File not found */ #[NoAdminRequired] - public function transcribeFile(string $path): DataResponse { + public function transcribeFile(string $path, string $appId, string $identifier): DataResponse { if ($path === '') { return new DataResponse('Empty file path received', Http::STATUS_BAD_REQUEST); } try { - $this->sttService->transcribeFile($path, $this->userId); - return new DataResponse(''); + $task = $this->sttService->transcribeFile($path, $this->userId, $appId, $identifier); + return new DataResponse([ + 'task' => $task->jsonSerializeCc(), + ]); } catch (NotFoundException $e) { $this->logger->error('Audio file not found: ' . $e->getMessage(), ['app' => Application::APP_ID]); return new DataResponse( diff --git a/lib/Controller/Text2ImageApiController.php b/lib/Controller/Text2ImageApiController.php index 9967cc67..1305100f 100644 --- a/lib/Controller/Text2ImageApiController.php +++ b/lib/Controller/Text2ImageApiController.php @@ -42,14 +42,17 @@ public function __construct( /** * Run or schedule an image generation task * - * @param string $appId - * @param string $identifier - * @param string $prompt - * @param int $nResults - * @param bool $displayPrompt - * @param bool $notifyReadyIfScheduled - * @param bool $schedule + * @param string $appId App id to be set in the created task + * @param string $identifier Identifier to be set in the created task + * @param string $prompt Input prompt for the image + * @param int $nResults Number of images to generate + * @param bool $displayPrompt Option to include the prompt when displaying the result images + * @param bool $notifyReadyIfScheduled Whether a notification will be produced when the tasks has run if it was scheduled + * @param bool $schedule Force scheduling even if the task could run synchronously * @return DataResponse|DataResponse + * + * 200: Task started successfully + * 400: Starting task is not possible */ #[NoAdminRequired] #[NoCSRFRequired] @@ -73,11 +76,12 @@ public function processPrompt( /** * Get one image of a generation * - * @param string $imageGenId - * @param int $fileNameId - * @return DataDisplayResponse>|DataResponse + * @param string $imageGenId ID of the image generation + * @param int $fileNameId ID of the file name + * @return DataDisplayResponse|DataResponse * * 200: Returns the image data + * 400: Getting image is not possible */ #[NoAdminRequired] #[NoCSRFRequired] @@ -104,10 +108,14 @@ public function getImage(string $imageGenId, int $fileNameId): DataDisplayRespon } */ + /** @var string $contentType */ + $contentType = $result['content-type']; + $contentType ??= 'image/jpeg'; + $response = new DataDisplayResponse( $result['image'] ?? '', Http::STATUS_OK, - ['Content-Type' => $result['content-type'] ?? 'image/jpeg'] + ['Content-Type' => $contentType] ); $response->cacheFor(60 * 60 * 24); return $response; @@ -116,7 +124,7 @@ public function getImage(string $imageGenId, int $fileNameId): DataDisplayRespon /** * Get image generation information * - * @param string $imageGenId + * @param string $imageGenId ID of the generation info * @return DataResponse|DataResponse * * 200: Returns the requested data @@ -149,9 +157,13 @@ public function getGenerationInfo(string $imageGenId): DataResponse { /** * Set visibility of images in one generation * - * @param string $imageGenId - * @param array $fileVisStatusArray + * @param string $imageGenId ID of the image generation + * @param array $fileVisStatusArray New file visibilities * @return DataResponse|DataResponse + * + * 200: Visiblity set successfully + * 400: Setting visibility is not possible + * 401: Setting visibility is not allowed */ #[NoAdminRequired] #[NoCSRFRequired] @@ -189,8 +201,10 @@ public function setVisibilityOfImageFiles(string $imageGenId, array $fileVisStat * as we don't want to keep the front-end waiting. * However, we still use rate limiting to prevent timing attacks. * - * @param string $imageGenId + * @param string $imageGenId ID of the image generation * @return DataResponse|DataResponse + * + * 200: Ready notification enabled successfully */ #[NoAdminRequired] #[NoCSRFRequired] @@ -216,9 +230,11 @@ public function notifyWhenReady(string $imageGenId): DataResponse { * (In theory bruteforce may be possible by a response timing attack but the attacker * won't gain access to the generation since its deleted during the attack.) * - * @param string $imageGenId + * @param string $imageGenId ID of the image generation * @return DataResponse|DataResponse * @throws NotPermittedException + * + * 200: Generation canceled successfully */ #[NoAdminRequired] #[NoCSRFRequired] diff --git a/lib/Service/SpeechToText/SpeechToTextService.php b/lib/Service/SpeechToText/SpeechToTextService.php index 1817017c..6a117e8b 100644 --- a/lib/Service/SpeechToText/SpeechToTextService.php +++ b/lib/Service/SpeechToText/SpeechToTextService.php @@ -25,6 +25,7 @@ use DateTime; use Exception; use InvalidArgumentException; +use OC\User\NoUserException; use OCA\Assistant\AppInfo\Application; use OCA\Assistant\Db\MetaTask; use OCA\Assistant\Db\MetaTaskMapper; @@ -33,6 +34,7 @@ use OCP\AppFramework\Http; use OCP\Files\File; use OCP\Files\Folder; +use OCP\Files\InvalidPathException; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -89,13 +91,17 @@ public function internalGetTask(string $userId, int $metaTaskId): MetaTask { /** * @param string $path * @param string|null $userId + * @param string $appId + * @param string $identifier + * @return MetaTask + * @throws InvalidPathException + * @throws NoUserException * @throws NotFoundException * @throws NotPermittedException * @throws PreConditionNotMetException - * @throws InvalidArgumentException - * @throws RuntimeException + * @throws \OCP\DB\Exception */ - public function transcribeFile(string $path, ?string $userId): void { + public function transcribeFile(string $path, ?string $userId, string $appId, string $identifier): MetaTask { // this also prevents NoUserException if (is_null($userId)) { throw new InvalidArgumentException('userId must not be null'); @@ -109,27 +115,33 @@ public function transcribeFile(string $path, ?string $userId): void { $this->speechToTextManager->scheduleFileTranscription($audioFile, $userId, Application::APP_ID); - $this->metaTaskMapper->createMetaTask( + return $this->metaTaskMapper->createMetaTask( $userId, ['fileId' => $audioFile->getId(), 'eTag' => $audioFile->getEtag()], '', time(), $audioFile->getId(), 'speech-to-text', - Application::APP_ID, + $appId, Application::STATUS_META_TASK_SCHEDULED, - Application::TASK_CATEGORY_SPEECH_TO_TEXT); + Application::TASK_CATEGORY_SPEECH_TO_TEXT, + $identifier + ); } /** * @param string $tempFileLocation * @param string|null $userId + * @param string $appId + * @param string $identifier + * @return MetaTask + * @throws InvalidPathException + * @throws NotFoundException * @throws NotPermittedException * @throws PreConditionNotMetException - * @throws InvalidArgumentException - * @throws RuntimeException + * @throws \OCP\DB\Exception */ - public function transcribeAudio(string $tempFileLocation, ?string $userId): void { + public function transcribeAudio(string $tempFileLocation, ?string $userId, string $appId, string $identifier): MetaTask { if ($userId === null) { throw new InvalidArgumentException('userId must not be null'); } @@ -138,16 +150,18 @@ public function transcribeAudio(string $tempFileLocation, ?string $userId): void $this->speechToTextManager->scheduleFileTranscription($audioFile, $userId, Application::APP_ID); - $this->metaTaskMapper->createMetaTask( + return $this->metaTaskMapper->createMetaTask( $userId, ['fileId' => $audioFile->getId(), 'eTag' => $audioFile->getEtag()], '', time(), $audioFile->getId(), 'speech-to-text', - Application::APP_ID, + $appId, Application::STATUS_META_TASK_SCHEDULED, - Application::TASK_CATEGORY_SPEECH_TO_TEXT); + Application::TASK_CATEGORY_SPEECH_TO_TEXT, + $identifier + ); } /** diff --git a/openapi.json b/openapi.json index 661e5fb9..1c2f8fa6 100644 --- a/openapi.json +++ b/openapi.json @@ -109,17 +109,23 @@ }, "PublicCapabilities": { "type": "object", - "additionalProperties": { - "type": "object", - "additionalProperties": { - "oneOf": [ - { - "type": "boolean" - }, - { + "required": [ + "assistant" + ], + "properties": { + "assistant": { + "type": "object", + "required": [ + "version" + ], + "properties": { + "version": { "type": "string" + }, + "enabled": { + "type": "boolean" } - ] + } } } }, @@ -208,6 +214,7 @@ "get": { "operationId": "task_management-get-available-task-types", "summary": "Get available task types", + "description": "Get all available task types that the assistant can handle.", "tags": [ "task_management" ], @@ -245,7 +252,7 @@ ], "responses": { "200": { - "description": "", + "description": "Available task types returned", "content": { "application/json": { "schema": { @@ -292,6 +299,7 @@ "get": { "operationId": "task_management-get-assistant-task", "summary": "Get an assistant task", + "description": "Get one specific task. It has to be a task owned by the current user.", "tags": [ "task_management" ], @@ -319,6 +327,7 @@ { "name": "metaTaskId", "in": "path", + "description": "ID of the task", "required": true, "schema": { "type": "integer", @@ -410,6 +419,7 @@ "delete": { "operationId": "task_management-delete-task", "summary": "Delete an assistant task", + "description": "This will cancel the task if needed and then delete it from the server.", "tags": [ "task_management" ], @@ -437,6 +447,7 @@ { "name": "metaTaskId", "in": "path", + "description": "ID of the task", "required": true, "schema": { "type": "integer", @@ -456,7 +467,7 @@ ], "responses": { "200": { - "description": "", + "description": "Task deleted successfully", "content": { "application/json": { "schema": { @@ -486,7 +497,7 @@ } }, "404": { - "description": "", + "description": "Task not found", "content": { "application/json": { "schema": { @@ -522,6 +533,7 @@ "get": { "operationId": "task_management-get-user-tasks", "summary": "Get user's tasks", + "description": "Get a list of assistant tasks for the current user.", "tags": [ "task_management" ], @@ -537,6 +549,7 @@ { "name": "taskType", "in": "query", + "description": "Task type id. If null, tasks of all task types will be retrieved", "schema": { "type": "string", "nullable": true @@ -545,6 +558,7 @@ { "name": "category", "in": "query", + "description": "Task category. If null, tasks of all categories will be retrieved", "schema": { "type": "integer", "format": "int64", @@ -576,7 +590,7 @@ ], "responses": { "200": { - "description": "", + "description": "User tasks returned", "content": { "application/json": { "schema": { @@ -617,7 +631,7 @@ } }, "404": { - "description": "", + "description": "No tasks found", "content": { "application/json": { "schema": { @@ -653,6 +667,7 @@ "post": { "operationId": "text_processing-run-text-processing-task", "summary": "Run a text processing task", + "description": "This endpoint will run the task synchronously.", "tags": [ "text_processing" ], @@ -668,6 +683,7 @@ { "name": "type", "in": "query", + "description": "Task type id", "required": true, "schema": { "type": "string" @@ -676,6 +692,7 @@ { "name": "inputs", "in": "query", + "description": "Input parameters", "required": true, "schema": { "type": "string" @@ -684,6 +701,7 @@ { "name": "appId", "in": "query", + "description": "App id to be set in the created task", "required": true, "schema": { "type": "string" @@ -692,6 +710,7 @@ { "name": "identifier", "in": "query", + "description": "Identifier to be set in the created task", "required": true, "schema": { "type": "string" @@ -722,7 +741,7 @@ ], "responses": { "200": { - "description": "", + "description": "Task started successfully", "content": { "application/json": { "schema": { @@ -760,7 +779,7 @@ } }, "400": { - "description": "", + "description": "Running task is not possible", "content": { "application/json": { "schema": { @@ -796,6 +815,7 @@ "post": { "operationId": "text_processing-schedule-text-processing-task", "summary": "Schedule a text processing task", + "description": "This endpoint will schedule the task for it to run as soon as possible.", "tags": [ "text_processing" ], @@ -811,6 +831,7 @@ { "name": "type", "in": "query", + "description": "Task type id", "required": true, "schema": { "type": "string" @@ -819,6 +840,7 @@ { "name": "inputs", "in": "query", + "description": "Input parameters", "required": true, "schema": { "type": "string" @@ -827,6 +849,7 @@ { "name": "appId", "in": "query", + "description": "App id to be set in the created task", "required": true, "schema": { "type": "string" @@ -835,6 +858,7 @@ { "name": "identifier", "in": "query", + "description": "Identifier to be set in the created task", "required": true, "schema": { "type": "string" @@ -865,7 +889,7 @@ ], "responses": { "200": { - "description": "", + "description": "Task scheduled", "content": { "application/json": { "schema": { @@ -903,7 +927,7 @@ } }, "400": { - "description": "", + "description": "Scheduling task is not possible", "content": { "application/json": { "schema": { @@ -939,7 +963,7 @@ "post": { "operationId": "text_processing-run-or-schedule-text-processing-task", "summary": "Run or schedule a text processing task", - "description": "If the task runs immediately or is schedule depends on the estimated runtime declared by the provider.", + "description": "This endpoint will either run or schedule the task.\nThe choice between run or schedule depends on the estimated runtime declared by the actual provider that will process the task.", "tags": [ "text_processing" ], @@ -955,6 +979,7 @@ { "name": "type", "in": "query", + "description": "Task type id", "required": true, "schema": { "type": "string" @@ -963,6 +988,7 @@ { "name": "inputs", "in": "query", + "description": "Input parameters", "required": true, "schema": { "type": "string" @@ -971,6 +997,7 @@ { "name": "appId", "in": "query", + "description": "App id to be set in the created task", "required": true, "schema": { "type": "string" @@ -979,6 +1006,7 @@ { "name": "identifier", "in": "query", + "description": "Identifier to be set in the created task", "required": true, "schema": { "type": "string" @@ -1009,7 +1037,7 @@ ], "responses": { "200": { - "description": "", + "description": "Task scheduled", "content": { "application/json": { "schema": { @@ -1047,7 +1075,7 @@ } }, "400": { - "description": "", + "description": "Scheduling task is not possible", "content": { "application/json": { "schema": { @@ -1099,6 +1127,7 @@ { "name": "filePath", "in": "query", + "description": "Path of the file to parse in the user's storage", "required": true, "schema": { "type": "string" @@ -1129,7 +1158,7 @@ ], "responses": { "200": { - "description": "", + "description": "Text parsed from file successfully", "content": { "application/json": { "schema": { @@ -1167,7 +1196,7 @@ } }, "400": { - "description": "", + "description": "Parsing text from file is not possible", "content": { "application/json": { "schema": { @@ -1202,6 +1231,8 @@ "/ocs/v2.php/apps/assistant/api/{apiVersion}/task/cancel/{metaTaskId}": { "put": { "operationId": "task_management-cancel-task", + "summary": "Cancel a task", + "description": "This endpoint will prevent a scheduled task to run by unscheduling it", "tags": [ "task_management" ], @@ -1229,6 +1260,7 @@ { "name": "metaTaskId", "in": "path", + "description": "ID of the task", "required": true, "schema": { "type": "integer", @@ -1248,7 +1280,7 @@ ], "responses": { "200": { - "description": "", + "description": "Task canceled successfully", "content": { "application/json": { "schema": { @@ -1278,7 +1310,7 @@ } }, "404": { - "description": "", + "description": "Task not found", "content": { "application/json": { "schema": { @@ -1329,6 +1361,7 @@ { "name": "appId", "in": "query", + "description": "App id to be set in the created task", "required": true, "schema": { "type": "string" @@ -1337,6 +1370,7 @@ { "name": "identifier", "in": "query", + "description": "Identifier to be set in the created task", "required": true, "schema": { "type": "string" @@ -1345,6 +1379,7 @@ { "name": "prompt", "in": "query", + "description": "Input prompt for the image", "required": true, "schema": { "type": "string" @@ -1353,6 +1388,7 @@ { "name": "nResults", "in": "query", + "description": "Number of images to generate", "schema": { "type": "integer", "format": "int64", @@ -1362,6 +1398,7 @@ { "name": "displayPrompt", "in": "query", + "description": "Option to include the prompt when displaying the result images", "schema": { "type": "integer", "default": 0, @@ -1374,6 +1411,7 @@ { "name": "notifyReadyIfScheduled", "in": "query", + "description": "Whether a notification will be produced when the tasks has run if it was scheduled", "schema": { "type": "integer", "default": 0, @@ -1386,6 +1424,7 @@ { "name": "schedule", "in": "query", + "description": "Force scheduling even if the task could run synchronously", "schema": { "type": "integer", "default": 0, @@ -1420,7 +1459,7 @@ ], "responses": { "200": { - "description": "", + "description": "Task started successfully", "content": { "application/json": { "schema": { @@ -1458,7 +1497,7 @@ } }, "400": { - "description": "", + "description": "Starting task is not possible", "content": { "application/json": { "schema": { @@ -1530,6 +1569,7 @@ { "name": "imageGenId", "in": "path", + "description": "ID of the generation info", "required": true, "schema": { "type": "string" @@ -1726,6 +1766,7 @@ { "name": "imageGenId", "in": "path", + "description": "ID of the image generation", "required": true, "schema": { "type": "string" @@ -1734,6 +1775,7 @@ { "name": "fileNameId", "in": "path", + "description": "ID of the file name", "required": true, "schema": { "type": "integer", @@ -1802,7 +1844,7 @@ } }, "400": { - "description": "", + "description": "Getting image is not possible", "content": { "application/json": { "schema": { @@ -1862,6 +1904,7 @@ { "name": "imageGenId", "in": "query", + "description": "ID of the image generation", "required": true, "schema": { "type": "string" @@ -1892,7 +1935,7 @@ ], "responses": { "200": { - "description": "", + "description": "Generation canceled successfully", "content": { "application/json": { "schema": { @@ -1986,6 +2029,7 @@ { "name": "fileVisStatusArray", "in": "query", + "description": "New file visibilities", "required": true, "schema": { "type": "string" @@ -2006,6 +2050,7 @@ { "name": "imageGenId", "in": "path", + "description": "ID of the image generation", "required": true, "schema": { "type": "string" @@ -2024,7 +2069,7 @@ ], "responses": { "200": { - "description": "", + "description": "Visiblity set successfully", "content": { "application/json": { "schema": { @@ -2054,7 +2099,7 @@ } }, "400": { - "description": "", + "description": "Setting visibility is not possible", "content": { "application/json": { "schema": { @@ -2092,7 +2137,7 @@ } }, "401": { - "description": "", + "description": "Setting visibility is not allowed", "content": { "application/json": { "schema": { @@ -2202,6 +2247,7 @@ { "name": "imageGenId", "in": "path", + "description": "ID of the image generation", "required": true, "schema": { "type": "string" @@ -2220,7 +2266,7 @@ ], "responses": { "200": { - "description": "", + "description": "Ready notification enabled successfully", "content": { "application/json": { "schema": { @@ -2293,7 +2339,8 @@ "/ocs/v2.php/apps/assistant/api/{apiVersion}/stt/transcribeAudio": { "post": { "operationId": "speech_to_text_api-transcribe-audio", - "summary": "Run audio transcription of an uploaded file", + "summary": "Transcribe uploaded audio file", + "description": "Schedule audio transcription of an uploaded file and return the created task.", "tags": [ "speech_to_text_api" ], @@ -2306,6 +2353,24 @@ } ], "parameters": [ + { + "name": "appId", + "in": "query", + "description": "App id to be set in the created task", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "identifier", + "in": "query", + "description": "Identifier to be set in the created task", + "required": true, + "schema": { + "type": "string" + } + }, { "name": "apiVersion", "in": "path", @@ -2331,7 +2396,7 @@ ], "responses": { "200": { - "description": "", + "description": "Task started successfully", "content": { "application/json": { "schema": { @@ -2351,7 +2416,15 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "string" + "type": "object", + "required": [ + "task" + ], + "properties": { + "task": { + "$ref": "#/components/schemas/Task" + } + } } } } @@ -2396,7 +2469,7 @@ } }, "400": { - "description": "", + "description": "Starting task is not possible", "content": { "application/json": { "schema": { @@ -2431,7 +2504,8 @@ "/ocs/v2.php/apps/assistant/api/{apiVersion}/stt/transcribeFile": { "post": { "operationId": "speech_to_text_api-transcribe-file", - "summary": "Run audio transcription of a user's file", + "summary": "Transcribe file from user's storage", + "description": "Schedule audio transcription of a user's storage file and return the created task", "tags": [ "speech_to_text_api" ], @@ -2453,6 +2527,24 @@ "type": "string" } }, + { + "name": "appId", + "in": "query", + "description": "App id to be set in the created task", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "identifier", + "in": "query", + "description": "Identifier to be set in the created task", + "required": true, + "schema": { + "type": "string" + } + }, { "name": "apiVersion", "in": "path", @@ -2478,7 +2570,7 @@ ], "responses": { "200": { - "description": "", + "description": "Task started successfully", "content": { "application/json": { "schema": { @@ -2498,7 +2590,15 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "string" + "type": "object", + "required": [ + "task" + ], + "properties": { + "task": { + "$ref": "#/components/schemas/Task" + } + } } } } @@ -2534,11 +2634,16 @@ } } } + }, + "text/plain": { + "schema": { + "type": "string" + } } } }, "400": { - "description": "", + "description": "Starting task is not possible", "content": { "application/json": { "schema": { @@ -2568,7 +2673,7 @@ } }, "404": { - "description": "", + "description": "File not found", "content": { "application/json": { "schema": { diff --git a/src/assistant.js b/src/assistant.js index 0eef889a..e2d22a0e 100644 --- a/src/assistant.js +++ b/src/assistant.js @@ -6,8 +6,12 @@ import { showError } from '@nextcloud/dialogs' __webpack_nonce__ = btoa(getRequestToken()) // eslint-disable-line __webpack_public_path__ = linkTo('assistant', 'js/') // eslint-disable-line +// only here to stay compatible with existing implementation using it export async function openAssistantTextProcessingForm(params) { - return openAssistantForm(params) + return openAssistantForm({ + ...params, + useMetaTasks: false, + }) } // TODO add param to lock on specific task type @@ -34,6 +38,7 @@ export async function openAssistantTextProcessingForm(params) { * onClick: (output) => { console.debug('second button clicked', output) }, * }, * ], + * useMetaTasks: true, * }).then(r => {console.debug('scheduled task', r.data.ocs.data.task)}) * * @param {object} params parameters for the assistant @@ -49,7 +54,7 @@ export async function openAssistantTextProcessingForm(params) { */ export async function openAssistantForm({ appId, identifier = '', taskType = null, input = '', - isInsideViewer = undefined, closeOnResult = false, actionButtons = undefined, useMetaTasks = false, + isInsideViewer = undefined, closeOnResult = false, actionButtons = undefined, useMetaTasks = true, }) { const { default: Vue } = await import(/* webpackChunkName: "vue-lazy" */'vue') const { default: AssistantTextProcessingModal } = await import(/* webpackChunkName: "assistant-modal-lazy" */'./components/AssistantTextProcessingModal.vue') @@ -102,17 +107,11 @@ export async function openAssistantForm({ view.showSyncTaskRunning = true view.inputs = inputs view.selectedTaskTypeId = taskTypeId - if (taskTypeId === 'speech-to-text') { - runSttTask(inputs).then(response => { - view.showScheduleConfirmation = true - view.loading = false - view.showSyncTaskRunning = false - }) - return - } - const runOrScheduleFunction = taskTypeId === 'OCP\\TextToImage\\Task' - ? runOrScheduleTtiTask - : runOrScheduleTask + const runOrScheduleFunction = taskTypeId === 'speech-to-text' + ? runSttTask + : taskTypeId === 'OCP\\TextToImage\\Task' + ? runOrScheduleTtiTask + : runOrScheduleTask runOrScheduleFunction(appId, newTaskIdentifier, taskTypeId, inputs) .then(async (response) => { const task = response.data?.ocs?.data?.task @@ -187,18 +186,24 @@ export async function openAssistantForm({ }) } -export async function runSttTask(inputs) { +export async function runSttTask(appId, identifier, taskType, inputs) { const { default: axios } = await import(/* webpackChunkName: "axios-lazy" */'@nextcloud/axios') const { generateOcsUrl } = await import(/* webpackChunkName: "router-gen-lazy" */'@nextcloud/router') saveLastSelectedTaskType('speech-to-text') if (inputs.sttMode === 'choose') { const url = generateOcsUrl('/apps/assistant/api/v1/stt/transcribeFile') - const params = { path: inputs.audioFilePath } + const params = { + appId, + identifier, + path: inputs.audioFilePath, + } return axios.post(url, params) } else { const url = generateOcsUrl('/apps/assistant/api/v1/stt/transcribeAudio') const formData = new FormData() formData.append('audioData', inputs.audioData) + formData.append('appId', appId) + formData.append('identifier', identifier) return axios.post(url, formData) } } @@ -358,7 +363,7 @@ async function showAssistantTaskResult(taskId) { const url = generateOcsUrl('/apps/assistant/api/v1/task/{taskId}', { taskId }) axios.get(url).then(response => { console.debug('showing results for task', response.data?.ocs?.data?.task) - openAssistantTaskResult(response.data?.ocs?.data?.task, true) + openAssistantTask(response.data?.ocs?.data?.task) }).catch(error => { console.error(error) showError(t('assistant', 'This task does not exist or has been cleaned up')) @@ -405,32 +410,19 @@ export async function openAssistantImageResult(metaTask) { window.open(url, '_blank') } +// only here to stay compatible with apps that already integrate the assistant, like Text +export async function openAssistantTaskResult(task) { + openAssistantTask(task, false) +} + /** * Open an assistant modal to show the result of a task * * @param {object} task the task we want to see the result of - * @param {boolean} useMetaTasks If false (default), treats the input task as an ocp task, otherwise as an assistant meta task + * @param {boolean} useMetaTasks If false, treats the input task as an ocp task, otherwise as an assistant meta task * @return {Promise} */ -export async function openAssistantTaskResult(task, useMetaTasks = false) { - // Divert to the right modal/page if we have a meta task with a category other than text generation: - if (useMetaTasks) { - switch (task.category) { - /* - case TASK_CATEGORIES.speech_to_text: - openAssistantPlainTextResult(task) - return - - case TASK_CATEGORIES.image_generation: - openAssistantImageResult(task) - return - */ - case TASK_CATEGORIES.text_generation: - default: - break - } - } - +export async function openAssistantTask(task, useMetaTasks = true) { const { default: Vue } = await import(/* webpackChunkName: "vue-lazy" */'vue') Vue.mixin({ methods: { t, n } }) const { showError } = await import(/* webpackChunkName: "dialogs-lazy" */'@nextcloud/dialogs') @@ -472,17 +464,11 @@ export async function openAssistantTaskResult(task, useMetaTasks = false) { view.showSyncTaskRunning = true view.inputs = inputs view.selectedTaskTypeId = taskTypeId - if (taskTypeId === 'speech-to-text') { - runSttTask(inputs).then(response => { - view.showScheduleConfirmation = true - view.loading = false - view.showSyncTaskRunning = false - }) - return - } - const runOrScheduleFunction = taskTypeId === 'OCP\\TextToImage\\Task' - ? runOrScheduleTtiTask - : runOrScheduleTask + const runOrScheduleFunction = taskTypeId === 'speech-to-text' + ? runSttTask + : taskTypeId === 'OCP\\TextToImage\\Task' + ? runOrScheduleTtiTask + : runOrScheduleTask runOrScheduleFunction(task.appId, newTaskIdentifier, taskTypeId, inputs) .then((response) => { // resolve(response.data?.ocs?.data?.task) @@ -556,7 +542,7 @@ export async function addAssistantMenuEntry() { }).$mount(menuEntry) view.$on('click', () => { - openAssistantTextProcessingForm({ appId: 'assistant', useMetaTasks: true }) + openAssistantForm({ appId: 'assistant' }) .then(r => { console.debug('scheduled task', r) }) diff --git a/src/main.js b/src/main.js index 15f220b7..5c9c9d07 100644 --- a/src/main.js +++ b/src/main.js @@ -1,7 +1,7 @@ import { handleNotification, addAssistantMenuEntry, openAssistantForm, openAssistantTextProcessingForm, - openAssistantTaskResult, + openAssistantTaskResult, openAssistantTask, } from './assistant.js' import { subscribe } from '@nextcloud/event-bus' import { loadState } from '@nextcloud/initial-state' @@ -20,6 +20,7 @@ function init() { openAssistantForm, openAssistantTextProcessingForm, openAssistantTaskResult, + openAssistantTask, } // to keep backward compatibility (with apps that already integrate the assistant, like Text) OCA.TPAssistant = OCA.Assistant diff --git a/src/views/TaskResultPage.vue b/src/views/TaskResultPage.vue index ab8ce052..85264f35 100644 --- a/src/views/TaskResultPage.vue +++ b/src/views/TaskResultPage.vue @@ -116,16 +116,11 @@ export default { this.showSyncTaskRunning = true this.task.inputs = inputs this.task.taskType = taskTypeId - if (taskTypeId === 'speech-to-text') { - runSttTask(inputs).then(response => { - this.showScheduleConfirmation = true - this.showSyncTaskRunning = false - }) - return - } - const runOrScheduleFunction = taskTypeId === 'OCP\\TextToImage\\Task' - ? runOrScheduleTtiTask - : runOrScheduleTask + const runOrScheduleFunction = taskTypeId === 'speech-to-text' + ? runSttTask + : taskTypeId === 'OCP\\TextToImage\\Task' + ? runOrScheduleTtiTask + : runOrScheduleTask runOrScheduleFunction(this.task.appId, this.task.identifier, taskTypeId, inputs) .then((response) => { console.debug('Assistant SYNC result', response.data?.ocs?.data)