diff --git a/.github/ISSUE_TEMPLATE/extension-update.yml b/.github/ISSUE_TEMPLATE/extension-update.yml new file mode 100644 index 000000000..769310933 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/extension-update.yml @@ -0,0 +1,54 @@ +name: πŸ”„Extension update +description: Submit an extension update +title: 'Extension update: ' +labels: [πŸ”„ Extension update] +body: + - type: markdown + attributes: + value: '# Extension update submission' + - type: textarea + id: description + attributes: + label: Changes + description: Describe the features you added or the bugs you fixed. + placeholder: This update adds... + - type: textarea + id: how-to + attributes: + label: How to use the new features + description: Describe how your new features can be used. + placeholder: If you put behavior X on a sprite, you can make a... + - type: checkboxes + id: checklist + attributes: + label: Checklist + description: Make sure you have done all of this before submitting! + options: + - label: "I've followed all of [the best practices](http://wiki.compilgames.net/doku.php/gdevelop5/extensions/best-practices)." + required: true + - label: I confirm that this extension can be integrated to this GitHub repository, distributed and MIT licensed. + required: true + - label: I am aware that the extension may be updated by anyone, and do not need my explicit consent to do so. + required: true + - type: textarea + id: example + attributes: + label: Example file + description: Please drag and drop an example project using your extension, compressed in a ZIP file, into this text field. **DO NOT PUT A LINK TO AN EXTERNAL SERVICE LIKE GOOGLE DRIVE!** + placeholder: '[MyExample.zip]()' + validations: + required: true + - type: textarea + id: extension + attributes: + label: Extension file + description: Please drag and drop your extension JSON file, compressed in a ZIP file, into this text field. **DO NOT PUT A LINK TO AN EXTERNAL SERVICE LIKE GOOGLE DRIVE!** + placeholder: '[MyExtension.json.zip]()' + validations: + required: true + - type: markdown + attributes: + value: | + You also may have to create an account on GitHub before posting. + Your extension will be added to the list after we have checked that it contains no virus and respects the best practices. + Thanks for contributing to GDevelop! πŸ™Œ diff --git a/.github/ISSUE_TEMPLATE/new-extension.yml b/.github/ISSUE_TEMPLATE/new-extension.yml index 805255f32..4ea5afbec 100644 --- a/.github/ISSUE_TEMPLATE/new-extension.yml +++ b/.github/ISSUE_TEMPLATE/new-extension.yml @@ -30,16 +30,6 @@ body: required: true - label: I am aware that the extension may be updated by anyone, and do not need my explicit consent to do so. required: true - - type: dropdown - id: tier - attributes: - label: 'What tier of review do you aim for your extension?' - description: '[More information](https://wiki.gdevelop.io/gdevelop5/extensions/tiers)' - options: - - Community (Unreviewed) - - Reviewed - validations: - required: true - type: textarea id: example attributes: diff --git a/.github/workflows/auto-pr.yml b/.github/workflows/auto-pr.yml index 76b305109..3be6b70e1 100644 --- a/.github/workflows/auto-pr.yml +++ b/.github/workflows/auto-pr.yml @@ -27,8 +27,8 @@ jobs: const { extractExtension } = require('./scripts/extract-extension.js'); const { verifyExtension } = require('./scripts/check-single-extension.js') - - const { error, extensionName } = await extractExtension("/tmp/ext.zip"); + const isUpdate = ${{ contains(github.event.issue.labels.*.name, 'πŸ”„ Extension update') }}; + const { error, extensionName, tier } = await extractExtension("/tmp/ext.zip", { isUpdate }); if(error === "zip-error") github.rest.issues.createComment({ @@ -62,6 +62,14 @@ jobs: body: `πŸ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are sorry, but the filename of the extension has unrecognized characters. Since filenames with non latin characters ("ASCII") can cause issues, our system won't allow file names with other characters than latin upper- and lowercase characters or numbers. Additionally, the first character must be an uppercase character. Please update your original submission post with a new zip file containing your extension with another file name following those guidelines πŸ™` }) + if(error === "nothing-to-update") + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `πŸ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are sorry, but the name of the extension you submitted for an update doesn't match any existing extension. If you want to update one of your ingoing extension submission, please follow the instruction on your first submission πŸ™` + }) + if(error) { core.setFailed("Extraction of the extension failed!"); return; @@ -90,7 +98,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `πŸ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are sorry, but it seems we already have a reviewed extension with that name. Extensions cannot be in both the community and reviewed extensions list at once. If you are trying to update that extension, please ask a member of the extension team for help. If the name clash is a coincidence, please update your original submission post with a new zip file containing your extension with a file name that is not already taken πŸ™` + body: `πŸ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are sorry, but it seems we already have a reviewed extension with that name. Extensions cannot be in both the experimental and reviewed extensions list at once. If you are trying to update that extension, please ask a member of the extension team for help. If the name clash is a coincidence, please update your original submission post with a new zip file containing your extension with a file name that is not already taken πŸ™` }) if(code === "invalid-json") @@ -106,7 +114,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `πŸ‘‹ Hey ${{ github.event.issue.user.login }}, thanks for your submission! It would seem you confused the extension file with your project file, and thus we cannot find your extension. Make sure you exported the extension itself from the extension editor as a standalone file, zip that standalone extension file, and make sure you did not confuse the "Example" and "Extension" fields while submitting!` + body: `πŸ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! It would seem you confused the extension file with your project file, and thus we cannot find your extension. Make sure you exported the extension itself from the extension editor as a standalone file, zip that standalone extension file, and make sure you did not confuse the "Example" and "Extension" fields while submitting!` }) if(code === "unknown-json-contents") @@ -114,7 +122,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `πŸ‘‹ Hey ${{ github.event.issue.user.login }}, thanks for your submission! It would seem your JSON file is not a valid GDevelop extension, although it is a JSON file. Please make sure you are exporting with the latest version of GDevelop and that you are not modifying the JSON incorrectly after the export.` + body: `πŸ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! It would seem your JSON file is not a valid GDevelop extension, although it is a JSON file. Please make sure you are exporting with the latest version of GDevelop and that you are not modifying the JSON incorrectly after the export.` }) if(code === "rule-break") @@ -122,11 +130,20 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `πŸ‘‹ Hey ${{ github.event.issue.user.login }}, thanks for your submission! Unfortunately, all submitted extensions have to meet some minimal quality standard - the extension best practices - and our system has found that your extension does not fully comply πŸ˜”. You can find all of those rules on [the GDevelop wiki](https://wiki.gdevelop.io/gdevelop5/extensions/best-practices). \n\nThe following issues have been found by the system concerning the respect of those best practices by your extension: \n\`\`\`\n${errors.reduce((acc, error) => `${acc}\n ⟢ ❌ ${error}`, '').slice(1)}\n\`\`\`\nPlease update your original submission post with a new zip file containing your extensions updated to follow those guidelines πŸ™` + body: `πŸ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! Unfortunately, all submitted extensions have to meet some minimal quality standard - the extension best practices - and our system has found that your extension does not fully comply πŸ˜”. You can find all of those rules on [the GDevelop wiki](https://wiki.gdevelop.io/gdevelop5/extensions/best-practices). \n\nThe following issues have been found by the system concerning the respect of those best practices by your extension: \n\`\`\`\n${errors.reduce((acc, error) => `${acc}\n ⟢ ❌ ${error}`, '').slice(1)}\n\`\`\`\nPlease update your original submission post with a new zip file containing your extensions updated to follow those guidelines πŸ™` }) if(code !== "success") core.setFailed("Verification of the extension failed!"); + if (isUpdate) { + github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: [tier === 'reviewed' ? 'πŸ” Reviewed extension' : 'πŸ§ͺ Experimental extension'] + }) + } + - name: Create Pull Request id: cpr uses: peter-evans/create-pull-request@v5 @@ -161,7 +178,7 @@ jobs: It can take a few seconds for the file to fully upload and show as the above. Once it is like shown above, click "Comment" and let the bot do the rest! - labels: ✨ New extension + labels: ${{github.event.issue.labels}} - name: Add card to pending review uses: peter-evans/create-or-update-project-card@v2 @@ -175,4 +192,4 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | gh issue close ${{ github.event.issue.number }} - gh issue comment ${{ github.event.issue.number }} --body "Hi @${{ github.event.issue.user.login }}! πŸ‘‹ This submission has passed all required tests, and has been moved to a PR as part of our submission pipeline. [You can see the progress of your submission on this page](${{ steps.cpr.outputs.pull-request-url }}). Community submissions are not reviewed by default, so your extension should be added once we've checked that your submission doesn't contain malicious code without further intervention on your part. If you wish for your extension to be reviewed (and thereby moved to the list of reviewed extensions), please follow the instructions written on the [README](https://github.com/GDevelopApp/GDevelop-extensions#get-your-extension-reviewed-extensions). Thanks again for your contribution to GDevelop!" + gh issue comment ${{ github.event.issue.number }} --body "Hi @${{ github.event.issue.user.login }}! πŸ‘‹ This submission has passed all preliminary tests, and has been moved to a PR where the review will be done. [You can see the progress and update your submission on this page](${{ steps.cpr.outputs.pull-request-url }}). Thanks again for your contribution to GDevelop!" diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml index ac55c0f55..8e457ad8f 100644 --- a/.github/workflows/commands.yml +++ b/.github/workflows/commands.yml @@ -75,7 +75,7 @@ jobs: run: | FILEURL=$(echo $BODY | grep -ioEh 'https?://\S+.zip' -m1) curl -L $FILEURL -o /tmp/ext.zip - unzip -o /tmp/ext.zip -d ./extensions/community + unzip -o /tmp/ext.zip -d ./extensions/${{ contains(github.event.issue.labels.*.name, 'πŸ” Reviewed extension') && 'reviewed' || 'community' }} - name: Rebuild the database run: | diff --git a/__tests__/auto-pr/auto-pr.spec.js b/__tests__/auto-pr/auto-pr.spec.js index 178b1ddde..76ad413dc 100644 --- a/__tests__/auto-pr/auto-pr.spec.js +++ b/__tests__/auto-pr/auto-pr.spec.js @@ -6,13 +6,16 @@ const TEMPORARY_MOCK_EXTENSIONS_FOLDER = __dirname + '/mock_extensions_folder'; const TEST_ZIPS_FOLDER = __dirname + '/test-zips'; const TEST_EXTENSIONS_FOLDER = __dirname + '/test-extensions'; -/** @param {string} zipName */ -const wrappedExtractExtension = async (zipName) => +/** + * @param {string} zipName + * @param {boolean | undefined} isUpdate + */ +const wrappedExtractExtension = async (zipName, isUpdate = false) => ( - await extractExtension( - `${TEST_ZIPS_FOLDER}/${zipName}.zip`, - TEMPORARY_MOCK_EXTENSIONS_FOLDER - ) + await extractExtension(`${TEST_ZIPS_FOLDER}/${zipName}.zip`, { + extensionsFolder: TEMPORARY_MOCK_EXTENSIONS_FOLDER, + isUpdate, + }) ).error; /** @param {string} extensionName */ @@ -45,7 +48,13 @@ describe('Auto-pr pipeline', () => { 'too-many-files' ); - expect(await wrappedExtractExtension(`valid-extension`)).toBeUndefined(); + expect(await wrappedExtractExtension(`new-extension`)).toBeUndefined(); + expect(await wrappedExtractExtension(`experimental-update`)).toBeUndefined(); + expect(await wrappedExtractExtension(`reviewed-update`)).toBeUndefined(); + + expect(await wrappedExtractExtension(`new-extension`, true)).toBe('nothing-to-update'); + expect(await wrappedExtractExtension(`experimental-update`, true)).toBeUndefined(); + expect(await wrappedExtractExtension(`reviewed-update`, true)).toBeUndefined(); }); test(`verifyExtension()`, async () => { diff --git a/__tests__/auto-pr/test-zips/BackButton.json b/__tests__/auto-pr/test-zips/BackButton.json new file mode 100644 index 000000000..21c2fe3d7 --- /dev/null +++ b/__tests__/auto-pr/test-zips/BackButton.json @@ -0,0 +1,109 @@ +{ + "author": "Arthur Pacaud (arthuro555)", + "description": "Prevents the back button from quitting the game and provides a condition to check when it's pressed (to allow customising its behavior).", + "extensionNamespace": "", + "fullName": "Back button", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWtleWJvYXJkLWJhY2tzcGFjZSIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik0yMSwxMUg2LjgzTDEwLjQxLDcuNDFMOSw2TDMsMTJMOSwxOEwxMC40MSwxNi41OEw2LjgzLDEzSDIxVjExWiIgLz48L3N2Zz4=", + "name": "BackButton", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/keyboard-backspace.svg", + "shortDescription": "Adds interactions with the back button.", + "version": "1.0.0", + "tags": [ + "back", + "mobile", + "button", + "input" + ], + "authorIds": [ + "ZgrsWuRTAkXgeuPV9bo0zuEcA2w1" + ], + "dependencies": [], + "eventsFunctions": [ + { + "description": "", + "fullName": "", + "functionType": "Action", + "name": "onFirstSceneLoaded", + "private": false, + "sentence": "", + "events": [ + { + "disabled": false, + "folded": false, + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "gdjs.evtTools.back_button = {\n triggered: false,\n _popStateListener: (event) => {\n gdjs.evtTools.back_button.triggered = true;\n history.pushState(\"\", \"\"); // Push a new fake state as the old one was popped\n }\n};\n\n// Handle back button on the web\nhistory.pushState(\"\", \"\"); // Push a fake state to prevent switching page when clicking on back\nwindow.addEventListener('popstate', gdjs.evtTools.back_button._popStateListener);\n\n// Handle back button on cordova\ndocument.addEventListener(\"backbutton\", e => {\n e.preventDefault();\n gdjs.evtTools.back_button.triggered = true;\n}, false); \n", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "Triggers whenever the player presses the back button.", + "fullName": "Back button is pressed", + "functionType": "Condition", + "name": "onBackButtonPressed", + "private": false, + "sentence": "Back button is pressed", + "events": [ + { + "disabled": false, + "folded": false, + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = gdjs.evtTools.back_button.triggered;\n", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "This simulates the normal action of the back button. \nThis action will quit the app when in a mobile app, and go back to the previous page when in a web browser.", + "fullName": "Trigger back button", + "functionType": "Action", + "name": "doDefault", + "private": false, + "sentence": "Simulate back button press", + "events": [ + { + "disabled": false, + "folded": false, + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "// Close the app on cordova, as this is the default behavior\nif (navigator.app) {\n navigator.app.exitApp();\n} else if (navigator.device && navigator.device.exitApp) {\n navigator.device.exitApp();\n} else {\n // Go to previous page as it is the default on browsers\n // Remove the listener so new fake states don't get pushed\n window.removeEventListener('popstate', gdjs.evtTools.back_button._popStateListener);\n history.back(); // Remove the state that prevents going back\n history.back(); // Actually go back\n}\n", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "", + "fullName": "", + "functionType": "Action", + "name": "onScenePostEvents", + "private": false, + "sentence": "", + "events": [ + { + "disabled": false, + "folded": false, + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "gdjs.evtTools.back_button.triggered = false;\n", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [] +} \ No newline at end of file diff --git a/__tests__/auto-pr/test-zips/experimental-update.zip b/__tests__/auto-pr/test-zips/experimental-update.zip new file mode 100644 index 000000000..12e8973b1 Binary files /dev/null and b/__tests__/auto-pr/test-zips/experimental-update.zip differ diff --git a/__tests__/auto-pr/test-zips/new-extension.zip b/__tests__/auto-pr/test-zips/new-extension.zip new file mode 100644 index 000000000..20ad3a583 Binary files /dev/null and b/__tests__/auto-pr/test-zips/new-extension.zip differ diff --git a/__tests__/auto-pr/test-zips/valid-extension.zip b/__tests__/auto-pr/test-zips/reviewed-update.zip similarity index 100% rename from __tests__/auto-pr/test-zips/valid-extension.zip rename to __tests__/auto-pr/test-zips/reviewed-update.zip diff --git a/package-lock.json b/package-lock.json index 767d131c1..8f33cb79d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", "dev": true, + "peer": true, "dependencies": { "@babel/code-frame": "^7.14.5", "@babel/generator": "^7.14.5", @@ -575,7 +576,6 @@ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", "dev": true, - "peer": true, "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1536,8 +1536,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/prettier": { "version": "2.3.2", @@ -1723,7 +1722,6 @@ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", "dev": true, - "peer": true, "dependencies": { "chalk": "^1.1.3", "esutils": "^2.0.2", @@ -1735,7 +1733,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -1745,7 +1742,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -1755,7 +1751,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -1771,15 +1766,13 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/babel-code-frame/node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, - "peer": true, "dependencies": { "ansi-regex": "^2.0.0" }, @@ -1792,7 +1785,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true, - "peer": true, "engines": { "node": ">=0.8.0" } @@ -1802,7 +1794,6 @@ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, - "peer": true, "dependencies": { "babel-code-frame": "^6.26.0", "babel-generator": "^6.26.0", @@ -1830,7 +1821,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -1840,7 +1830,6 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", "dev": true, - "peer": true, "bin": { "json5": "lib/cli.js" } @@ -1849,15 +1838,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/babel-core/node_modules/slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -1867,7 +1854,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -1911,7 +1897,6 @@ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", "dev": true, - "peer": true, "dependencies": { "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" @@ -2009,7 +1994,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", "dev": true, - "peer": true, "dependencies": { "@babel/runtime": "^7.7.2", "cosmiconfig": "^6.0.0", @@ -2021,7 +2005,6 @@ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", "dev": true, - "peer": true, "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.1.0", @@ -2038,7 +2021,6 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, - "peer": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -2055,7 +2037,6 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "peer": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -2074,7 +2055,6 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -2146,7 +2126,6 @@ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", "dev": true, - "peer": true, "dependencies": { "babel-core": "^6.26.0", "babel-runtime": "^6.26.0", @@ -2162,7 +2141,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -2172,7 +2150,6 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, - "peer": true, "dependencies": { "source-map": "^0.5.6" } @@ -2198,7 +2175,6 @@ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", "dev": true, - "peer": true, "dependencies": { "babel-runtime": "^6.26.0", "babel-traverse": "^6.26.0", @@ -2212,7 +2188,6 @@ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", "dev": true, - "peer": true, "dependencies": { "babel-code-frame": "^6.26.0", "babel-messages": "^6.23.0", @@ -2230,7 +2205,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "dependencies": { "ms": "2.0.0" } @@ -2240,7 +2214,6 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -2249,8 +2222,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/babel-types": { "version": "6.26.0", @@ -3290,7 +3262,6 @@ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", "dev": true, - "peer": true, "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.1" @@ -3603,7 +3574,6 @@ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, - "peer": true, "dependencies": { "loose-envify": "^1.0.0" } @@ -5408,8 +5378,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json5": { "version": "2.2.0", @@ -5480,8 +5449,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/load-json-file": { "version": "4.0.0", @@ -5604,7 +5572,6 @@ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, - "peer": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -6184,7 +6151,6 @@ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -6256,7 +6222,6 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "peer": true, "dependencies": { "callsites": "^3.0.0" }, @@ -6319,7 +6284,6 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -6517,7 +6481,6 @@ "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -6605,8 +6568,7 @@ "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/repeating": { "version": "2.0.1", @@ -7381,7 +7343,6 @@ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, - "peer": true, "engines": { "node": ">= 6" } @@ -7435,6 +7396,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", "dev": true, + "peer": true, "requires": { "@babel/code-frame": "^7.14.5", "@babel/generator": "^7.14.5", @@ -7828,7 +7790,6 @@ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", "dev": true, - "peer": true, "requires": { "regenerator-runtime": "^0.14.0" } @@ -8653,8 +8614,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true, - "peer": true + "dev": true }, "@types/prettier": { "version": "2.3.2", @@ -8806,7 +8766,6 @@ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", "dev": true, - "peer": true, "requires": { "chalk": "^1.1.3", "esutils": "^2.0.2", @@ -8817,22 +8776,19 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "peer": true + "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true, - "peer": true + "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, - "peer": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -8845,15 +8801,13 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true, - "peer": true + "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, - "peer": true, "requires": { "ansi-regex": "^2.0.0" } @@ -8862,8 +8816,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true, - "peer": true + "dev": true } } }, @@ -8872,7 +8825,6 @@ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, - "peer": true, "requires": { "babel-code-frame": "^6.26.0", "babel-generator": "^6.26.0", @@ -8900,7 +8852,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "requires": { "ms": "2.0.0" } @@ -8909,29 +8860,25 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", - "dev": true, - "peer": true + "dev": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", - "dev": true, - "peer": true + "dev": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "peer": true + "dev": true } } }, @@ -8970,7 +8917,6 @@ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", "dev": true, - "peer": true, "requires": { "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" @@ -9055,7 +9001,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", "dev": true, - "peer": true, "requires": { "@babel/runtime": "^7.7.2", "cosmiconfig": "^6.0.0", @@ -9067,7 +9012,6 @@ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", "dev": true, - "peer": true, "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.1.0", @@ -9081,7 +9025,6 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, - "peer": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -9092,7 +9035,6 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "peer": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -9104,8 +9046,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "peer": true + "dev": true } } }, @@ -9169,7 +9110,6 @@ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", "dev": true, - "peer": true, "requires": { "babel-core": "^6.26.0", "babel-runtime": "^6.26.0", @@ -9184,15 +9124,13 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "peer": true + "dev": true }, "source-map-support": { "version": "0.4.18", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, - "peer": true, "requires": { "source-map": "^0.5.6" } @@ -9222,7 +9160,6 @@ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", "dev": true, - "peer": true, "requires": { "babel-runtime": "^6.26.0", "babel-traverse": "^6.26.0", @@ -9236,7 +9173,6 @@ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", "dev": true, - "peer": true, "requires": { "babel-code-frame": "^6.26.0", "babel-messages": "^6.23.0", @@ -9254,7 +9190,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "peer": true, "requires": { "ms": "2.0.0" } @@ -9263,15 +9198,13 @@ "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true, - "peer": true + "dev": true }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "peer": true + "dev": true } } }, @@ -10069,7 +10002,6 @@ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", "dev": true, - "peer": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.1" @@ -10316,7 +10248,6 @@ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, - "peer": true, "requires": { "loose-envify": "^1.0.0" } @@ -11775,8 +11706,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "peer": true + "dev": true }, "json5": { "version": "2.2.0", @@ -11832,8 +11762,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "peer": true + "dev": true }, "load-json-file": { "version": "4.0.0", @@ -11936,7 +11865,6 @@ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, - "peer": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } @@ -12403,8 +12331,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", - "dev": true, - "peer": true + "dev": true }, "os-tmpdir": { "version": "1.0.2", @@ -12452,7 +12379,6 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "peer": true, "requires": { "callsites": "^3.0.0" } @@ -12499,8 +12425,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "peer": true + "dev": true }, "picomatch": { "version": "2.3.0", @@ -12642,8 +12567,7 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true, - "peer": true + "dev": true }, "process-nextick-args": { "version": "2.0.1", @@ -12719,8 +12643,7 @@ "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true, - "peer": true + "dev": true }, "repeating": { "version": "2.0.1", @@ -13314,8 +13237,7 @@ "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "peer": true + "dev": true }, "yargs": { "version": "16.2.0", diff --git a/scripts/extract-extension.js b/scripts/extract-extension.js index bf50cc413..dbfa1699e 100644 --- a/scripts/extract-extension.js +++ b/scripts/extract-extension.js @@ -8,13 +8,15 @@ const pipeline = require('util').promisify(require('stream').pipeline); /** * Extracts exactly one extension into the community extensions folder from a zip file. * @param {string} zipPath The path to the zip file to extract. - * @param {string} [extensionsFolder] The folder with the extensions. - * @returns {Promise<{error: "too-many-files" | "no-json-found"| "invalid-file-name" | "zip-error", details?: any} | {error?: undefined,extensionName: string}>} the name of the extracted extension if successful, else a generic error code. + * @param {{extensionsFolder?: string, preliminaryCheck?: boolean, isUpdate?: boolean}} [options] + * @returns {Promise<{error: "too-many-files" | "no-json-found"| "invalid-file-name" | "zip-error" | "nothing-to-update", details?: any} | {error?: undefined,extensionName: string, tier: string}>} the name of the extracted extension if successful, else a generic error code. */ -exports.extractExtension = async function ( - zipPath, - extensionsFolder = `${__dirname}/../extensions` -) { +exports.extractExtension = async function (zipPath, options) { + const { + extensionsFolder = `${__dirname}/../extensions`, + preliminaryCheck = false, + isUpdate = false, + } = options || {}; // Load in the archive with JSZip const zip = await JSZip.loadAsync(await readFile(zipPath)).catch((e) => { console.warn(`JSZip loading error caught: `, e); @@ -39,16 +41,34 @@ exports.extractExtension = async function ( if (!isValidExtensionName(extensionName)) return { error: 'invalid-file-name' }; + let tier = 'community'; + if (isUpdate) { + const [community, reviewed] = await Promise.all([ + readFile(`${extensionsFolder}/community/${extensionName}.json`).catch( + () => null + ), + readFile(`${extensionsFolder}/reviewed/${extensionName}.json`).catch( + () => null + ), + ]); + if (!community && !reviewed) { + return { error: 'nothing-to-update' }; + } + if (reviewed) { + tier = 'reviewed'; + } + } + try { - // Write the extension to the community extensions folder + // Write the extension to the community or reviewed extensions folder await pipeline( file.nodeStream(), - createWriteStream(`${extensionsFolder}/community/${file.name}`) + createWriteStream(`${extensionsFolder}/${tier}/${file.name}`) ); } catch (e) { console.warn(`JSZip extraction error caught: `, e); return { error: 'zip-error' }; } - return { extensionName }; + return { extensionName, tier }; };