├── .editorconfig ├── .gitattributes ├── .github └── workflows │ └── unit-tests.yml ├── .gitignore ├── .nvmrc ├── .redport ├── cookiecutter_replay │ └── cookiecutter-vscode-extension.json ├── manifest.rpt.json └── patches │ └── disable-install-step.patch ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .yarn ├── patches │ └── @vscode-vsce-npm-2.21.1.patch ├── plugins │ └── @yarnpkg │ │ └── plugin-outdated.cjs ├── releases │ ├── LICENSE │ └── yarn-4.4.1.cjs └── sdks │ ├── LICENSE │ ├── integrations.yml │ └── typescript │ ├── bin │ ├── tsc │ └── tsserver │ ├── lib │ ├── tsc.js │ ├── tsserver.js │ ├── tsserverlibrary.js │ └── typescript.js │ └── package.json ├── .yarnrc.yml ├── LICENSE ├── README.md ├── extension ├── .eslintrc.yaml ├── .gitignore ├── LICENSE.txt ├── README.md ├── contrib │ └── build.mjs ├── examples │ ├── PKGBUILD │ ├── debian │ │ └── foo.install │ ├── dymoprint │ └── foo.install ├── images │ ├── screenshot-customizepkg-patch.png │ ├── screenshot-pkgbuild-with-extension.png │ └── screenshot-pkgbuild-without-extension.png ├── package.json ├── share │ ├── context.sh │ ├── dist │ │ └── package.json │ └── language │ │ ├── aur-pkgbuild.language-configuration.json │ │ ├── aur-pkgbuild.tmLanguage.json │ │ ├── customizepkg-patch.language-configuration.json │ │ ├── customizepkg-patch.tmLanguage.json │ │ ├── pacman-install-script.language-configuration.json │ │ └── pacman-install-script.tmLanguage.json ├── src │ ├── extension.ts │ ├── language.ts │ ├── log.ts │ ├── shellcheck.ts │ └── time.ts └── tsconfig.json ├── package.json ├── packaging ├── .eslintrc.yaml ├── .gitignore ├── jest.config.json ├── package.json ├── tsconfig.json └── tsconfig.linting.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [.gitattributes] 13 | indent_size = 16 14 | 15 | [*.{diff,patch}] 16 | end_of_line = lf 17 | trim_trailing_whitespace = false 18 | 19 | [*.json] 20 | indent_size = 2 21 | 22 | [*.md] 23 | indent_size = 2 24 | trim_trailing_whitespace = false 25 | 26 | [*.{mjs,ts}] 27 | indent_size = 2 28 | 29 | [*.{yaml,yml}] 30 | indent_size = 2 31 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # CAUTION: 2 | # Always run the following command after adding/editing an 3 | # `eol` entry: 4 | # 5 | # git add --renormalize FILES_WITH_AFFECTED_EXTENSION 6 | # 7 | # This keeps existing files consistent with the new setting. 8 | # 9 | # Example: 10 | # 11 | # git add --renormalize '*.foo' '*.bar' 12 | 13 | .editorconfig text eol=lf 14 | .gitattributes text eol=lf 15 | .gitignore text eol=lf 16 | 17 | # LF required for interactive patching as of Git 2.17.1 18 | *.diff text eol=lf 19 | *.patch text eol=lf 20 | 21 | *.json text eol=lf 22 | *.md text eol=lf 23 | *.mjs text eol=lf 24 | *.ts text eol=lf 25 | *.txt text eol=lf 26 | *.yaml text eol=lf 27 | *.yml text eol=lf 28 | 29 | # No need to diff or patch these 30 | /.yarn/plugins/** binary 31 | /.yarn/releases/*.cjs binary 32 | /.yarn/sdks/** binary 33 | -------------------------------------------------------------------------------- /.github/workflows/unit-tests.yml: -------------------------------------------------------------------------------- 1 | name: Run unit tests 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-22.04 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | 12 | - name: Use specified Node.js version 13 | uses: actions/setup-node@v2 14 | with: 15 | node-version-file: .nvmrc 16 | 17 | - name: Install dependencies 18 | run: yarn install 19 | 20 | - name: Compile 21 | run: yarn compile 22 | 23 | - name: Run linter 24 | run: yarn lint 25 | 26 | - name: Run unit tests 27 | run: yarn test 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.pnp.* 2 | /.yarn/* 3 | !/.yarn/patches/ 4 | !/.yarn/plugins/ 5 | !/.yarn/releases/ 6 | !/.yarn/sdks/ 7 | !/.yarn/versions/ 8 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/hydrogen 2 | -------------------------------------------------------------------------------- /.redport/cookiecutter_replay/cookiecutter-vscode-extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "cookiecutter": { 3 | "extension_display_name": "Packaging", 4 | "extension_slug": "packaging", 5 | "project_slug": "vscode-packaging", 6 | "extension_description": "", 7 | "extension_license": "Apache-2.0", 8 | "vscode_engine_min_version_tuple": "1.92", 9 | "contribute_language": "y", 10 | "first_language_display_name": "PKGBUILD (AUR)", 11 | "first_language_slug": "aur-pkgbuild", 12 | "first_language_filename_pattern": "PKGBUILD", 13 | "first_language_scope_group": "source", 14 | "dedicated_library_workspace": "y", 15 | "author_full_name": "Claudia Pellegrino", 16 | "copyright_holder_full_name": "Claudia Pellegrino", 17 | "publish_on_visual_studio_marketplace": "y", 18 | "marketplace_publisher_id": "claui", 19 | "github_username": "claui", 20 | "install_dependencies_now": "y", 21 | "_copy_without_render": [ 22 | ".redport/patches/*.patch" 23 | ], 24 | "_extensions": [ 25 | "local_extensions.CustomFunctionsExtension", 26 | "local_extensions.CustomGlobalsExtension" 27 | ], 28 | "_license_filename": "", 29 | "_template": "vscode", 30 | "_output_dir": "REDACTED", 31 | "_repo_dir": "REDACTED", 32 | "_checkout": null 33 | }, 34 | "_cookiecutter": { 35 | "extension_display_name": "", 36 | "extension_slug": "{{ cookiecutter.extension_display_name.lower().replace(' ', '-').replace('_', '-') }}", 37 | "project_slug": "vscode-{{ cookiecutter.extension_slug }}", 38 | "extension_description": "", 39 | "extension_license": [ 40 | "Apache-2.0", 41 | "Proprietary" 42 | ], 43 | "vscode_engine_min_version_tuple": "1.92", 44 | "contribute_language": "y", 45 | "first_language_display_name": "{{ cookiecutter.extension_display_name }}", 46 | "first_language_slug": "{{ cookiecutter.first_language_display_name.lower().replace(' ', '-').replace('_', '-') }}", 47 | "first_language_filename_pattern": "*.{{ cookiecutter.first_language_slug }}", 48 | "first_language_scope_group": [ 49 | "source", 50 | "text" 51 | ], 52 | "dedicated_library_workspace": "y", 53 | "author_full_name": "Claudia Pellegrino", 54 | "copyright_holder_full_name": "{{ cookiecutter.author_full_name }}", 55 | "publish_on_visual_studio_marketplace": "y", 56 | "marketplace_publisher_id": "", 57 | "github_username": "claui", 58 | "install_dependencies_now": "y" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /.redport/manifest.rpt.json: -------------------------------------------------------------------------------- 1 | { 2 | "upstream": { 3 | "type": "cookiecutter-template", 4 | "source": "https://github.com/claui/cookiecutter-vscode-extension.git", 5 | "commit": "c8234db3a55fe3b2e9afca365d58ecc3ed7ae76d", 6 | "replay": "cookiecutter_replay/cookiecutter-vscode-extension.json", 7 | "patches": [ 8 | "patches/disable-install-step.patch" 9 | ], 10 | "nextPatches": [ 11 | "patches/disable-install-step.patch" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.redport/patches/disable-install-step.patch: -------------------------------------------------------------------------------- 1 | diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py 2 | index b77ddf3..48ee9b3 100644 3 | --- a/hooks/post_gen_project.py 4 | +++ b/hooks/post_gen_project.py 5 | @@ -1,23 +1,5 @@ 6 | -import logging 7 | import os 8 | -from pathlib import Path, PurePath 9 | import shutil 10 | -import subprocess 11 | -import sys 12 | - 13 | -from cookiecutter.config import get_user_config 14 | - 15 | -logger = logging.getLogger(__name__) 16 | - 17 | -logger.info('Saving replay file for redport') 18 | -config_dict = get_user_config() 19 | -template_name = '{{ cookiecutter._repo_dir.split('/')[-1] }}' 20 | -target_replay_path = Path('.redport') / 'cookiecutter_replay' 21 | -target_replay_path.mkdir(exist_ok=True) 22 | -shutil.copy( 23 | - (PurePath(config_dict['replay_dir']) / template_name).with_suffix('.json'), 24 | - target_replay_path, 25 | -) 26 | 27 | shutil.rmtree('licenses') 28 | 29 | @@ -30,57 +12,3 @@ os.remove('extension/share/language/language-configuration.json') 30 | {%- if cookiecutter.dedicated_library_workspace == "n" %} 31 | shutil.rmtree('./{{ cookiecutter.extension_slug }}') 32 | {%- endif %} 33 | - 34 | -git_commands = [ 35 | - 'git init -q', 36 | - 'git add .', 37 | - {%- if cookiecutter.contribute_language == "y" %} 38 | - 'git reset -q extension/examples extension/share/language', 39 | - 'git add -N extension/examples extension/share/language', 40 | - {%- endif %} 41 | - 'git reset -q extension/README.md', 42 | - 'git add -N extension/README.md', 43 | - {%- if cookiecutter.dedicated_library_workspace == "y" %} 44 | - 'git reset -q {{ cookiecutter.extension_slug }}/src {{ cookiecutter.extension_slug }}/test', 45 | - 'git add -N {{ cookiecutter.extension_slug }}/src {{ cookiecutter.extension_slug }}/test', 46 | - {%- endif %} 47 | -] 48 | - 49 | -for git_command in git_commands: 50 | - subprocess.run( 51 | - git_command, check=True, shell=True, stdout=sys.stderr, 52 | - ) 53 | - 54 | -{%- if cookiecutter.install_dependencies_now == "y" %} 55 | -def sysexit_formatted(message: str) -> None: 56 | - width = max((len(line) for line in message)) 57 | - print('', width * '-', *message, width * '-', 58 | - file=sys.stderr, sep='\n') 59 | - sys.exit() 60 | - 61 | -install_commands = [ 62 | - 'yarn init -2', 63 | - 'git checkout package.json', 64 | - 'yarn set version 4', 65 | - 'yarn plugin import https://go.mskelton.dev/yarn-outdated/v4', 66 | - 'yarn install', 67 | - 'yarn clean-install', 68 | - 'git add .yarn .yarnrc.yml package.json yarn.lock', 69 | -] 70 | - 71 | -try: 72 | - for install_command in install_commands: 73 | - subprocess.run( 74 | - install_command, check=True, shell=True, stdout=sys.stderr, 75 | - ) 76 | -except subprocess.CalledProcessError as e: 77 | - sysexit_formatted([ 78 | - f'Shell command failed with exit code {e.returncode}.', 79 | - 'Go to the {{ cookiecutter.project_slug }}' 80 | - ' directory and re-run:', 81 | - *[ 82 | - f' {command}' 83 | - for command in ['nvm use'] + install_commands 84 | - ], 85 | - ]) 86 | -{%- endif %} 87 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "arcanis.vscode-zipfs", 4 | "davidanson.vscode-markdownlint", 5 | "dbaeumer.vscode-eslint", 6 | "editorconfig.editorconfig", 7 | "henrynguyen5-vsc.vsc-nvm", 8 | "orta.vscode-jest", 9 | "redhat.vscode-yaml" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Launch Extension", 5 | "type": "extensionHost", 6 | "request": "launch", 7 | "args": [ 8 | "--extensionDevelopmentPath=${workspaceFolder}/extension/build" 9 | ], 10 | "outFiles": [ 11 | "${workspaceFolder}/extension/build/**/*.js", 12 | "${workspaceFolder}/extension/build/**/*.js.map" 13 | ], 14 | "preLaunchTask": "Compile" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[javascript]": { 3 | "editor.defaultFormatter": "dbaeumer.vscode-eslint", 4 | "editor.formatOnSave": true, 5 | "editor.rulers": [ 6 | 80 7 | ] 8 | }, 9 | "[json]": { 10 | "editor.defaultFormatter": "vscode.json-language-features" 11 | }, 12 | "[jsonc]": { 13 | "editor.defaultFormatter": "vscode.json-language-features" 14 | }, 15 | "[typescript]": { 16 | "editor.defaultFormatter": "dbaeumer.vscode-eslint", 17 | "editor.formatOnSave": true, 18 | "editor.rulers": [ 19 | 80 20 | ] 21 | }, 22 | "[yaml]": { 23 | "editor.defaultFormatter": "redhat.vscode-yaml" 24 | }, 25 | "eslint.format.enable": true, 26 | "eslint.nodePath": ".yarn/sdks", 27 | "files.exclude": { 28 | "**/.git": true, 29 | "**/packaging/lib": true 30 | }, 31 | "jest.jestCommandLine": "if ! type nvm > /dev/null && [ \"${NVM_DIR}\" ] && [ -s \"${NVM_DIR}/nvm.sh\" ]; then . \"${NVM_DIR}/nvm.sh\"; nvm use; fi; node --version && yarn test", 32 | "json.schemas": [ 33 | { 34 | "fileMatch": [ 35 | "*.tmLanguage.json" 36 | ], 37 | "url": "https://raw.githubusercontent.com/Septh/tmlanguage/master/tmlanguage.json" 38 | } 39 | ], 40 | "markdownlint.config": { 41 | "MD033": false 42 | }, 43 | "search.exclude": { 44 | "/extension/build": true, 45 | "/extension/dist": true, 46 | "/extension/types": true, 47 | "/extension/work": true, 48 | "/packaging/build": true, 49 | "/packaging/dist": true, 50 | "/packaging/types": true, 51 | "**/.yarn": true, 52 | "**/.pnp.*": true 53 | }, 54 | "typescript.enablePromptUseWorkspaceTsdk": true, 55 | "typescript.tsdk": ".yarn/sdks/typescript/lib" 56 | } 57 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "Compile", 6 | "type": "shell", 7 | "command": "if ! type nvm > /dev/null && [ \"${NVM_DIR}\" ] && [ -s \"${NVM_DIR}/nvm.sh\" ]; then . \"${NVM_DIR}/nvm.sh\"; nvm use; fi; node --version && yarn compile", 8 | "args": [], 9 | "problemMatcher": [ 10 | "$tsc" 11 | ], 12 | "presentation": { 13 | "reveal": "silent" 14 | }, 15 | "group": { 16 | "kind": "build", 17 | "isDefault": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.yarn/patches/@vscode-vsce-npm-2.21.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/out/main.js b/out/main.js 2 | index 652b1fa7c6ec4ee91646cececcb7b4371ac120d5..6f5bdaef2ccb42132df0521537eb1479b7eb31bd 100644 3 | --- a/out/main.js 4 | +++ b/out/main.js 5 | @@ -77,6 +77,7 @@ module.exports = function (argv) { 6 | commander_1.default 7 | .command('ls') 8 | .description('Lists all the files that will be published') 9 | + .option('-C, --cwd ', 'Start in as the current working directory.') 10 | .option('--yarn', 'Use yarn instead of npm (default inferred from presence of yarn.lock or .yarnrc)') 11 | .option('--no-yarn', 'Use npm instead of yarn (default inferred from lack of yarn.lock or .yarnrc)') 12 | .option('--packagedDependencies ', 'Select packages that should be published only (includes dependencies)', (val, all) => (all ? all.concat(val) : [val]), undefined) 13 | @@ -84,7 +85,7 @@ module.exports = function (argv) { 14 | // default must remain undefined for dependencies or we will fail to load defaults from package.json 15 | .option('--dependencies', 'Enable dependency detection via npm or yarn', undefined) 16 | .option('--no-dependencies', 'Disable dependency detection via npm or yarn', undefined) 17 | - .action(({ yarn, packagedDependencies, ignoreFile, dependencies }) => main((0, package_1.ls)({ useYarn: yarn, packagedDependencies, ignoreFile, dependencies }))); 18 | + .action(({ cwd, yarn, packagedDependencies, ignoreFile, dependencies }) => main((0, package_1.ls)({ cwd, useYarn: yarn, packagedDependencies, ignoreFile, dependencies }))); 19 | commander_1.default 20 | .command('package [version]') 21 | .alias('pack') 22 | @@ -92,6 +93,7 @@ module.exports = function (argv) { 23 | .option('-o, --out ', 'Output .vsix extension file to location (defaults to -.vsix)') 24 | .option('-t, --target ', `Target architecture. Valid targets: ${ValidTargets}`) 25 | .option('-m, --message ', 'Commit message used when calling `npm version`.') 26 | + .option('-C, --cwd ', 'Start in as the current working directory.') 27 | .option('--no-git-tag-version', 'Do not create a version commit and tag when calling `npm version`. Valid only when [version] is provided.') 28 | .option('--no-update-package-json', 'Do not update `package.json`. Valid only when [version] is provided.') 29 | .option('--githubBranch ', 'The GitHub branch used to infer relative links in README.md. Can be overridden by --baseContentUrl and --baseImagesUrl.') 30 | @@ -111,11 +113,12 @@ module.exports = function (argv) { 31 | .option('--allow-star-activation', 'Allow using * in activation events') 32 | .option('--allow-missing-repository', 'Allow missing a repository URL in package.json') 33 | .option('--skip-license', 'Allow packaging without license file') 34 | - .action((version, { out, target, message, gitTagVersion, updatePackageJson, githubBranch, gitlabBranch, rewriteRelativeLinks, baseContentUrl, baseImagesUrl, yarn, ignoreFile, gitHubIssueLinking, gitLabIssueLinking, dependencies, preRelease, allowStarActivation, allowMissingRepository, skipLicense, }) => main((0, package_1.packageCommand)({ 35 | + .action((version, { out, target, message, cwd, gitTagVersion, updatePackageJson, githubBranch, gitlabBranch, rewriteRelativeLinks, baseContentUrl, baseImagesUrl, yarn, ignoreFile, gitHubIssueLinking, gitLabIssueLinking, dependencies, preRelease, allowStarActivation, allowMissingRepository, skipLicense, }) => main((0, package_1.packageCommand)({ 36 | packagePath: out, 37 | version, 38 | target, 39 | commitMessage: message, 40 | + cwd, 41 | gitTagVersion, 42 | updatePackageJson, 43 | githubBranch, 44 | @@ -139,6 +142,7 @@ module.exports = function (argv) { 45 | .option('-p, --pat ', 'Personal Access Token (defaults to VSCE_PAT environment variable)', process.env['VSCE_PAT']) 46 | .option('-t, --target ', `Target architectures. Valid targets: ${ValidTargets}`) 47 | .option('-m, --message ', 'Commit message used when calling `npm version`.') 48 | + .option('-C, --cwd ', 'Start in as the current working directory.') 49 | .option('--no-git-tag-version', 'Do not create a version commit and tag when calling `npm version`. Valid only when [version] is provided.') 50 | .option('--no-update-package-json', 'Do not update `package.json`. Valid only when [version] is provided.') 51 | .option('-i, --packagePath ', 'Publish the provided VSIX packages.') 52 | @@ -158,11 +162,12 @@ module.exports = function (argv) { 53 | .option('--allow-missing-repository', 'Allow missing a repository URL in package.json') 54 | .option('--skip-duplicate', 'Fail silently if version already exists on the marketplace') 55 | .option('--skip-license', 'Allow publishing without license file') 56 | - .action((version, { pat, target, message, gitTagVersion, updatePackageJson, packagePath, githubBranch, gitlabBranch, baseContentUrl, baseImagesUrl, yarn, noVerify, ignoreFile, dependencies, preRelease, allowStarActivation, allowMissingRepository, skipDuplicate, skipLicense, }) => main((0, publish_1.publish)({ 57 | + .action((version, { pat, target, message, cwd, gitTagVersion, updatePackageJson, packagePath, githubBranch, gitlabBranch, baseContentUrl, baseImagesUrl, yarn, noVerify, ignoreFile, dependencies, preRelease, allowStarActivation, allowMissingRepository, skipDuplicate, skipLicense, }) => main((0, publish_1.publish)({ 58 | pat, 59 | version, 60 | targets: target, 61 | commitMessage: message, 62 | + cwd, 63 | gitTagVersion, 64 | updatePackageJson, 65 | packagePath, 66 | -------------------------------------------------------------------------------- /.yarn/plugins/@yarnpkg/plugin-outdated.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | //prettier-ignore 3 | module.exports = { 4 | name: "@yarnpkg/plugin-outdated", 5 | factory: function (require) { 6 | var plugin=(()=>{var _r=Object.create,ye=Object.defineProperty,xr=Object.defineProperties,br=Object.getOwnPropertyDescriptor,Sr=Object.getOwnPropertyDescriptors,vr=Object.getOwnPropertyNames,tt=Object.getOwnPropertySymbols,Hr=Object.getPrototypeOf,rt=Object.prototype.hasOwnProperty,wr=Object.prototype.propertyIsEnumerable;var nt=(e,t,r)=>t in e?ye(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,w=(e,t)=>{for(var r in t||(t={}))rt.call(t,r)&&nt(e,r,t[r]);if(tt)for(var r of tt(t))wr.call(t,r)&&nt(e,r,t[r]);return e},B=(e,t)=>xr(e,Sr(t)),Tr=e=>ye(e,"__esModule",{value:!0});var W=e=>{if(typeof require!="undefined")return require(e);throw new Error('Dynamic require of "'+e+'" is not supported')};var G=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),$r=(e,t)=>{for(var r in t)ye(e,r,{get:t[r],enumerable:!0})},Lr=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of vr(t))!rt.call(e,n)&&n!=="default"&&ye(e,n,{get:()=>t[n],enumerable:!(r=br(t,n))||r.enumerable});return e},J=e=>Lr(Tr(ye(e!=null?_r(Hr(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var He=G(Y=>{"use strict";Y.isInteger=e=>typeof e=="number"?Number.isInteger(e):typeof e=="string"&&e.trim()!==""?Number.isInteger(Number(e)):!1;Y.find=(e,t)=>e.nodes.find(r=>r.type===t);Y.exceedsLimit=(e,t,r=1,n)=>n===!1||!Y.isInteger(e)||!Y.isInteger(t)?!1:(Number(t)-Number(e))/Number(r)>=n;Y.escapeNode=(e,t=0,r)=>{let n=e.nodes[t];!n||(r&&n.type===r||n.type==="open"||n.type==="close")&&n.escaped!==!0&&(n.value="\\"+n.value,n.escaped=!0)};Y.encloseBrace=e=>e.type!=="brace"?!1:e.commas>>0+e.ranges>>0==0?(e.invalid=!0,!0):!1;Y.isInvalidBrace=e=>e.type!=="brace"?!1:e.invalid===!0||e.dollar?!0:e.commas>>0+e.ranges>>0==0||e.open!==!0||e.close!==!0?(e.invalid=!0,!0):!1;Y.isOpenOrClose=e=>e.type==="open"||e.type==="close"?!0:e.open===!0||e.close===!0;Y.reduce=e=>e.reduce((t,r)=>(r.type==="text"&&t.push(r.value),r.type==="range"&&(r.type="text"),t),[]);Y.flatten=(...e)=>{let t=[],r=n=>{for(let s=0;s{"use strict";var st=He();at.exports=(e,t={})=>{let r=(n,s={})=>{let a=t.escapeInvalid&&st.isInvalidBrace(s),i=n.invalid===!0&&t.escapeInvalid===!0,o="";if(n.value)return(a||i)&&st.isOpenOrClose(n)?"\\"+n.value:n.value;if(n.value)return n.value;if(n.nodes)for(let h of n.nodes)o+=r(h);return o};return r(e)}});var ot=G((ts,it)=>{"use strict";it.exports=function(e){return typeof e=="number"?e-e==0:typeof e=="string"&&e.trim()!==""?Number.isFinite?Number.isFinite(+e):isFinite(+e):!1}});var yt=G((rs,dt)=>{"use strict";var ut=ot(),ce=(e,t,r)=>{if(ut(e)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(t===void 0||e===t)return String(e);if(ut(t)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let n=w({relaxZeros:!0},r);typeof n.strictZeros=="boolean"&&(n.relaxZeros=n.strictZeros===!1);let s=String(n.relaxZeros),a=String(n.shorthand),i=String(n.capture),o=String(n.wrap),h=e+":"+t+"="+s+a+i+o;if(ce.cache.hasOwnProperty(h))return ce.cache[h].result;let d=Math.min(e,t),f=Math.max(e,t);if(Math.abs(d-f)===1){let m=e+"|"+t;return n.capture?`(${m})`:n.wrap===!1?m:`(?:${m})`}let R=gt(e)||gt(t),p={min:e,max:t,a:d,b:f},v=[],A=[];if(R&&(p.isPadded=R,p.maxLen=String(p.max).length),d<0){let m=f<0?Math.abs(f):1;A=ct(m,Math.abs(d),p,n),d=p.a=0}return f>=0&&(v=ct(d,f,p,n)),p.negatives=A,p.positives=v,p.result=Or(A,v,n),n.capture===!0?p.result=`(${p.result})`:n.wrap!==!1&&v.length+A.length>1&&(p.result=`(?:${p.result})`),ce.cache[h]=p,p.result};function Or(e,t,r){let n=De(e,t,"-",!1,r)||[],s=De(t,e,"",!1,r)||[],a=De(e,t,"-?",!0,r)||[];return n.concat(a).concat(s).join("|")}function kr(e,t){let r=1,n=1,s=pt(e,r),a=new Set([t]);for(;e<=s&&s<=t;)a.add(s),r+=1,s=pt(e,r);for(s=ft(t+1,n)-1;e1&&o.count.pop(),o.count.push(f.count[0]),o.string=o.pattern+ht(o.count),i=d+1;continue}r.isPadded&&(R=Mr(d,r,n)),f.string=R+f.pattern+ht(f.count),a.push(f),i=d+1,o=f}return a}function De(e,t,r,n,s){let a=[];for(let i of e){let{string:o}=i;!n&&!lt(t,"string",o)&&a.push(r+o),n&<(t,"string",o)&&a.push(r+o)}return a}function Ir(e,t){let r=[];for(let n=0;nt?1:t>e?-1:0}function lt(e,t,r){return e.some(n=>n[t]===r)}function pt(e,t){return Number(String(e).slice(0,-t)+"9".repeat(t))}function ft(e,t){return e-e%Math.pow(10,t)}function ht(e){let[t=0,r=""]=e;return r||t>1?`{${t+(r?","+r:"")}}`:""}function Pr(e,t,r){return`[${e}${t-e==1?"":"-"}${t}]`}function gt(e){return/^-?(0+)\d/.test(e)}function Mr(e,t,r){if(!t.isPadded)return e;let n=Math.abs(t.maxLen-String(e).length),s=r.relaxZeros!==!1;switch(n){case 0:return"";case 1:return s?"0?":"0";case 2:return s?"0{0,2}":"00";default:return s?`0{0,${n}}`:`0{${n}}`}}ce.cache={};ce.clearCache=()=>ce.cache={};dt.exports=ce});var Be=G((ns,bt)=>{"use strict";var Br=W("util"),Rt=yt(),At=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),Ur=e=>t=>e===!0?Number(t):String(t),Pe=e=>typeof e=="number"||typeof e=="string"&&e!=="",Re=e=>Number.isInteger(+e),Me=e=>{let t=`${e}`,r=-1;if(t[0]==="-"&&(t=t.slice(1)),t==="0")return!1;for(;t[++r]==="0";);return r>0},Gr=(e,t,r)=>typeof e=="string"||typeof t=="string"?!0:r.stringify===!0,Fr=(e,t,r)=>{if(t>0){let n=e[0]==="-"?"-":"";n&&(e=e.slice(1)),e=n+e.padStart(n?t-1:t,"0")}return r===!1?String(e):e},mt=(e,t)=>{let r=e[0]==="-"?"-":"";for(r&&(e=e.slice(1),t--);e.length{e.negatives.sort((i,o)=>io?1:0),e.positives.sort((i,o)=>io?1:0);let r=t.capture?"":"?:",n="",s="",a;return e.positives.length&&(n=e.positives.join("|")),e.negatives.length&&(s=`-(${r}${e.negatives.join("|")})`),n&&s?a=`${n}|${s}`:a=n||s,t.wrap?`(${r}${a})`:a},Ct=(e,t,r,n)=>{if(r)return Rt(e,t,w({wrap:!1},n));let s=String.fromCharCode(e);if(e===t)return s;let a=String.fromCharCode(t);return`[${s}-${a}]`},Et=(e,t,r)=>{if(Array.isArray(e)){let n=r.wrap===!0,s=r.capture?"":"?:";return n?`(${s}${e.join("|")})`:e.join("|")}return Rt(e,t,r)},_t=(...e)=>new RangeError("Invalid range arguments: "+Br.inspect(...e)),xt=(e,t,r)=>{if(r.strictRanges===!0)throw _t([e,t]);return[]},Kr=(e,t)=>{if(t.strictRanges===!0)throw new TypeError(`Expected step "${e}" to be a number`);return[]},qr=(e,t,r=1,n={})=>{let s=Number(e),a=Number(t);if(!Number.isInteger(s)||!Number.isInteger(a)){if(n.strictRanges===!0)throw _t([e,t]);return[]}s===0&&(s=0),a===0&&(a=0);let i=s>a,o=String(e),h=String(t),d=String(r);r=Math.max(Math.abs(r),1);let f=Me(o)||Me(h)||Me(d),R=f?Math.max(o.length,h.length,d.length):0,p=f===!1&&Gr(e,t,n)===!1,v=n.transform||Ur(p);if(n.toRegex&&r===1)return Ct(mt(e,R),mt(t,R),!0,n);let A={negatives:[],positives:[]},m=k=>A[k<0?"negatives":"positives"].push(Math.abs(k)),E=[],b=0;for(;i?s>=a:s<=a;)n.toRegex===!0&&r>1?m(s):E.push(Fr(v(s,b),R,p)),s=i?s-r:s+r,b++;return n.toRegex===!0?r>1?jr(A,n):Et(E,null,w({wrap:!1},n)):E},Wr=(e,t,r=1,n={})=>{if(!Re(e)&&e.length>1||!Re(t)&&t.length>1)return xt(e,t,n);let s=n.transform||(p=>String.fromCharCode(p)),a=`${e}`.charCodeAt(0),i=`${t}`.charCodeAt(0),o=a>i,h=Math.min(a,i),d=Math.max(a,i);if(n.toRegex&&r===1)return Ct(h,d,!1,n);let f=[],R=0;for(;o?a>=i:a<=i;)f.push(s(a,R)),a=o?a-r:a+r,R++;return n.toRegex===!0?Et(f,null,{wrap:!1,options:n}):f},Te=(e,t,r,n={})=>{if(t==null&&Pe(e))return[e];if(!Pe(e)||!Pe(t))return xt(e,t,n);if(typeof r=="function")return Te(e,t,1,{transform:r});if(At(r))return Te(e,t,0,r);let s=w({},n);return s.capture===!0&&(s.wrap=!0),r=r||s.step||1,Re(r)?Re(e)&&Re(t)?qr(e,t,r,s):Wr(e,t,Math.max(Math.abs(r),1),s):r!=null&&!At(r)?Kr(r,s):Te(e,t,1,r)};bt.exports=Te});var Ht=G((ss,vt)=>{"use strict";var Qr=Be(),St=He(),Xr=(e,t={})=>{let r=(n,s={})=>{let a=St.isInvalidBrace(s),i=n.invalid===!0&&t.escapeInvalid===!0,o=a===!0||i===!0,h=t.escapeInvalid===!0?"\\":"",d="";if(n.isOpen===!0||n.isClose===!0)return h+n.value;if(n.type==="open")return o?h+n.value:"(";if(n.type==="close")return o?h+n.value:")";if(n.type==="comma")return n.prev.type==="comma"?"":o?n.value:"|";if(n.value)return n.value;if(n.nodes&&n.ranges>0){let f=St.reduce(n.nodes),R=Qr(...f,B(w({},t),{wrap:!1,toRegex:!0}));if(R.length!==0)return f.length>1&&R.length>1?`(${R})`:R}if(n.nodes)for(let f of n.nodes)d+=r(f,n);return d};return r(e)};vt.exports=Xr});var $t=G((as,Tt)=>{"use strict";var zr=Be(),wt=we(),pe=He(),le=(e="",t="",r=!1)=>{let n=[];if(e=[].concat(e),t=[].concat(t),!t.length)return e;if(!e.length)return r?pe.flatten(t).map(s=>`{${s}}`):t;for(let s of e)if(Array.isArray(s))for(let a of s)n.push(le(a,t,r));else for(let a of t)r===!0&&typeof a=="string"&&(a=`{${a}}`),n.push(Array.isArray(a)?le(s,a,r):s+a);return pe.flatten(n)},Zr=(e,t={})=>{let r=t.rangeLimit===void 0?1e3:t.rangeLimit,n=(s,a={})=>{s.queue=[];let i=a,o=a.queue;for(;i.type!=="brace"&&i.type!=="root"&&i.parent;)i=i.parent,o=i.queue;if(s.invalid||s.dollar){o.push(le(o.pop(),wt(s,t)));return}if(s.type==="brace"&&s.invalid!==!0&&s.nodes.length===2){o.push(le(o.pop(),["{}"]));return}if(s.nodes&&s.ranges>0){let R=pe.reduce(s.nodes);if(pe.exceedsLimit(...R,t.step,r))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let p=zr(...R,t);p.length===0&&(p=wt(s,t)),o.push(le(o.pop(),p)),s.nodes=[];return}let h=pe.encloseBrace(s),d=s.queue,f=s;for(;f.type!=="brace"&&f.type!=="root"&&f.parent;)f=f.parent,d=f.queue;for(let R=0;R{"use strict";Lt.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` 7 | `,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var Pt=G((os,Dt)=>{"use strict";var Vr=we(),{MAX_LENGTH:kt,CHAR_BACKSLASH:Ue,CHAR_BACKTICK:Yr,CHAR_COMMA:Jr,CHAR_DOT:en,CHAR_LEFT_PARENTHESES:tn,CHAR_RIGHT_PARENTHESES:rn,CHAR_LEFT_CURLY_BRACE:nn,CHAR_RIGHT_CURLY_BRACE:sn,CHAR_LEFT_SQUARE_BRACKET:Nt,CHAR_RIGHT_SQUARE_BRACKET:It,CHAR_DOUBLE_QUOTE:an,CHAR_SINGLE_QUOTE:on,CHAR_NO_BREAK_SPACE:un,CHAR_ZERO_WIDTH_NOBREAK_SPACE:cn}=Ot(),ln=(e,t={})=>{if(typeof e!="string")throw new TypeError("Expected a string");let r=t||{},n=typeof r.maxLength=="number"?Math.min(kt,r.maxLength):kt;if(e.length>n)throw new SyntaxError(`Input length (${e.length}), exceeds max characters (${n})`);let s={type:"root",input:e,nodes:[]},a=[s],i=s,o=s,h=0,d=e.length,f=0,R=0,p,v={},A=()=>e[f++],m=E=>{if(E.type==="text"&&o.type==="dot"&&(o.type="text"),o&&o.type==="text"&&E.type==="text"){o.value+=E.value;return}return i.nodes.push(E),E.parent=i,E.prev=o,o=E,E};for(m({type:"bos"});f0){if(i.ranges>0){i.ranges=0;let E=i.nodes.shift();i.nodes=[E,{type:"text",value:Vr(i)}]}m({type:"comma",value:p}),i.commas++;continue}if(p===en&&R>0&&i.commas===0){let E=i.nodes;if(R===0||E.length===0){m({type:"text",value:p});continue}if(o.type==="dot"){if(i.range=[],o.value+=p,o.type="range",i.nodes.length!==3&&i.nodes.length!==5){i.invalid=!0,i.ranges=0,o.type="text";continue}i.ranges++,i.args=[];continue}if(o.type==="range"){E.pop();let b=E[E.length-1];b.value+=o.value+p,o=b,i.ranges--;continue}m({type:"dot",value:p});continue}m({type:"text",value:p})}do if(i=a.pop(),i.type!=="root"){i.nodes.forEach(k=>{k.nodes||(k.type==="open"&&(k.isOpen=!0),k.type==="close"&&(k.isClose=!0),k.nodes||(k.type="text"),k.invalid=!0)});let E=a[a.length-1],b=E.nodes.indexOf(i);E.nodes.splice(b,1,...i.nodes)}while(a.length>0);return m({type:"eos"}),s};Dt.exports=ln});var Ut=G((us,Bt)=>{"use strict";var Mt=we(),pn=Ht(),fn=$t(),hn=Pt(),z=(e,t={})=>{let r=[];if(Array.isArray(e))for(let n of e){let s=z.create(n,t);Array.isArray(s)?r.push(...s):r.push(s)}else r=[].concat(z.create(e,t));return t&&t.expand===!0&&t.nodupes===!0&&(r=[...new Set(r)]),r};z.parse=(e,t={})=>hn(e,t);z.stringify=(e,t={})=>typeof e=="string"?Mt(z.parse(e,t),t):Mt(e,t);z.compile=(e,t={})=>(typeof e=="string"&&(e=z.parse(e,t)),pn(e,t));z.expand=(e,t={})=>{typeof e=="string"&&(e=z.parse(e,t));let r=fn(e,t);return t.noempty===!0&&(r=r.filter(Boolean)),t.nodupes===!0&&(r=[...new Set(r)]),r};z.create=(e,t={})=>e===""||e.length<3?[e]:t.expand!==!0?z.compile(e,t):z.expand(e,t);Bt.exports=z});var Ae=G((cs,qt)=>{"use strict";var gn=W("path"),ne="\\\\/",Gt=`[^${ne}]`,ae="\\.",dn="\\+",yn="\\?",$e="\\/",Rn="(?=.)",Ft="[^/]",Ge=`(?:${$e}|$)`,jt=`(?:^|${$e})`,Fe=`${ae}{1,2}${Ge}`,An=`(?!${ae})`,mn=`(?!${jt}${Fe})`,Cn=`(?!${ae}{0,1}${Ge})`,En=`(?!${Fe})`,_n=`[^.${$e}]`,xn=`${Ft}*?`,Kt={DOT_LITERAL:ae,PLUS_LITERAL:dn,QMARK_LITERAL:yn,SLASH_LITERAL:$e,ONE_CHAR:Rn,QMARK:Ft,END_ANCHOR:Ge,DOTS_SLASH:Fe,NO_DOT:An,NO_DOTS:mn,NO_DOT_SLASH:Cn,NO_DOTS_SLASH:En,QMARK_NO_DOT:_n,STAR:xn,START_ANCHOR:jt},bn=B(w({},Kt),{SLASH_LITERAL:`[${ne}]`,QMARK:Gt,STAR:`${Gt}*?`,DOTS_SLASH:`${ae}{1,2}(?:[${ne}]|$)`,NO_DOT:`(?!${ae})`,NO_DOTS:`(?!(?:^|[${ne}])${ae}{1,2}(?:[${ne}]|$))`,NO_DOT_SLASH:`(?!${ae}{0,1}(?:[${ne}]|$))`,NO_DOTS_SLASH:`(?!${ae}{1,2}(?:[${ne}]|$))`,QMARK_NO_DOT:`[^.${ne}]`,START_ANCHOR:`(?:^|[${ne}])`,END_ANCHOR:`(?:[${ne}]|$)`}),Sn={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};qt.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:Sn,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:gn.sep,extglobChars(e){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${e.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(e){return e===!0?bn:Kt}}});var me=G(Q=>{"use strict";var vn=W("path"),Hn=process.platform==="win32",{REGEX_BACKSLASH:wn,REGEX_REMOVE_BACKSLASH:Tn,REGEX_SPECIAL_CHARS:$n,REGEX_SPECIAL_CHARS_GLOBAL:Ln}=Ae();Q.isObject=e=>e!==null&&typeof e=="object"&&!Array.isArray(e);Q.hasRegexChars=e=>$n.test(e);Q.isRegexChar=e=>e.length===1&&Q.hasRegexChars(e);Q.escapeRegex=e=>e.replace(Ln,"\\$1");Q.toPosixSlashes=e=>e.replace(wn,"/");Q.removeBackslashes=e=>e.replace(Tn,t=>t==="\\"?"":t);Q.supportsLookbehinds=()=>{let e=process.version.slice(1).split(".").map(Number);return e.length===3&&e[0]>=9||e[0]===8&&e[1]>=10};Q.isWindows=e=>e&&typeof e.windows=="boolean"?e.windows:Hn===!0||vn.sep==="\\";Q.escapeLast=(e,t,r)=>{let n=e.lastIndexOf(t,r);return n===-1?e:e[n-1]==="\\"?Q.escapeLast(e,t,n-1):`${e.slice(0,n)}\\${e.slice(n)}`};Q.removePrefix=(e,t={})=>{let r=e;return r.startsWith("./")&&(r=r.slice(2),t.prefix="./"),r};Q.wrapOutput=(e,t={},r={})=>{let n=r.contains?"":"^",s=r.contains?"":"$",a=`${n}(?:${e})${s}`;return t.negated===!0&&(a=`(?:^(?!${a}).*$)`),a}});var Jt=G((ps,Yt)=>{"use strict";var Wt=me(),{CHAR_ASTERISK:je,CHAR_AT:On,CHAR_BACKWARD_SLASH:Ce,CHAR_COMMA:kn,CHAR_DOT:Ke,CHAR_EXCLAMATION_MARK:qe,CHAR_FORWARD_SLASH:Qt,CHAR_LEFT_CURLY_BRACE:We,CHAR_LEFT_PARENTHESES:Qe,CHAR_LEFT_SQUARE_BRACKET:Nn,CHAR_PLUS:In,CHAR_QUESTION_MARK:Xt,CHAR_RIGHT_CURLY_BRACE:Dn,CHAR_RIGHT_PARENTHESES:zt,CHAR_RIGHT_SQUARE_BRACKET:Pn}=Ae(),Zt=e=>e===Qt||e===Ce,Vt=e=>{e.isPrefix!==!0&&(e.depth=e.isGlobstar?Infinity:1)},Mn=(e,t)=>{let r=t||{},n=e.length-1,s=r.parts===!0||r.scanToEnd===!0,a=[],i=[],o=[],h=e,d=-1,f=0,R=0,p=!1,v=!1,A=!1,m=!1,E=!1,b=!1,k=!1,N=!1,ee=!1,F=!1,ie=0,j,C,H={value:"",depth:0,isGlob:!1},U=()=>d>=n,l=()=>h.charCodeAt(d+1),L=()=>(j=C,h.charCodeAt(++d));for(;d0&&(oe=h.slice(0,f),h=h.slice(f),R-=f),T&&A===!0&&R>0?(T=h.slice(0,R),u=h.slice(R)):A===!0?(T="",u=h):T=h,T&&T!==""&&T!=="/"&&T!==h&&Zt(T.charCodeAt(T.length-1))&&(T=T.slice(0,-1)),r.unescape===!0&&(u&&(u=Wt.removeBackslashes(u)),T&&k===!0&&(T=Wt.removeBackslashes(T)));let c={prefix:oe,input:e,start:f,base:T,glob:u,isBrace:p,isBracket:v,isGlob:A,isExtglob:m,isGlobstar:E,negated:N,negatedExtglob:ee};if(r.tokens===!0&&(c.maxDepth=0,Zt(C)||i.push(H),c.tokens=i),r.parts===!0||r.tokens===!0){let K;for(let S=0;S{"use strict";var Le=Ae(),Z=me(),{MAX_LENGTH:Oe,POSIX_REGEX_SOURCE:Bn,REGEX_NON_SPECIAL_CHARS:Un,REGEX_SPECIAL_CHARS_BACKREF:Gn,REPLACEMENTS:er}=Le,Fn=(e,t)=>{if(typeof t.expandRange=="function")return t.expandRange(...e,t);e.sort();let r=`[${e.join("-")}]`;try{new RegExp(r)}catch(n){return e.map(s=>Z.escapeRegex(s)).join("..")}return r},fe=(e,t)=>`Missing ${e}: "${t}" - use "\\\\${t}" to match literal characters`,tr=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");e=er[e]||e;let r=w({},t),n=typeof r.maxLength=="number"?Math.min(Oe,r.maxLength):Oe,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);let a={type:"bos",value:"",output:r.prepend||""},i=[a],o=r.capture?"":"?:",h=Z.isWindows(t),d=Le.globChars(h),f=Le.extglobChars(d),{DOT_LITERAL:R,PLUS_LITERAL:p,SLASH_LITERAL:v,ONE_CHAR:A,DOTS_SLASH:m,NO_DOT:E,NO_DOT_SLASH:b,NO_DOTS_SLASH:k,QMARK:N,QMARK_NO_DOT:ee,STAR:F,START_ANCHOR:ie}=d,j=y=>`(${o}(?:(?!${ie}${y.dot?m:R}).)*?)`,C=r.dot?"":E,H=r.dot?N:ee,U=r.bash===!0?j(r):F;r.capture&&(U=`(${U})`),typeof r.noext=="boolean"&&(r.noextglob=r.noext);let l={input:e,index:-1,start:0,dot:r.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:i};e=Z.removePrefix(e,l),s=e.length;let L=[],T=[],oe=[],u=a,c,K=()=>l.index===s-1,S=l.peek=(y=1)=>e[l.index+y],te=l.advance=()=>e[++l.index]||"",re=()=>e.slice(l.index+1),X=(y="",$=0)=>{l.consumed+=y,l.index+=$},xe=y=>{l.output+=y.output!=null?y.output:y.value,X(y.value)},Cr=()=>{let y=1;for(;S()==="!"&&(S(2)!=="("||S(3)==="?");)te(),l.start++,y++;return y%2==0?!1:(l.negated=!0,l.start++,!0)},be=y=>{l[y]++,oe.push(y)},ue=y=>{l[y]--,oe.pop()},x=y=>{if(u.type==="globstar"){let $=l.braces>0&&(y.type==="comma"||y.type==="brace"),g=y.extglob===!0||L.length&&(y.type==="pipe"||y.type==="paren");y.type!=="slash"&&y.type!=="paren"&&!$&&!g&&(l.output=l.output.slice(0,-u.output.length),u.type="star",u.value="*",u.output=U,l.output+=u.output)}if(L.length&&y.type!=="paren"&&(L[L.length-1].inner+=y.value),(y.value||y.output)&&xe(y),u&&u.type==="text"&&y.type==="text"){u.value+=y.value,u.output=(u.output||"")+y.value;return}y.prev=u,i.push(y),u=y},Se=(y,$)=>{let g=B(w({},f[$]),{conditions:1,inner:""});g.prev=u,g.parens=l.parens,g.output=l.output;let _=(r.capture?"(":"")+g.open;be("parens"),x({type:y,value:$,output:l.output?"":A}),x({type:"paren",extglob:!0,value:te(),output:_}),L.push(g)},Er=y=>{let $=y.close+(r.capture?")":""),g;if(y.type==="negate"){let _=U;y.inner&&y.inner.length>1&&y.inner.includes("/")&&(_=j(r)),(_!==U||K()||/^\)+$/.test(re()))&&($=y.close=`)$))${_}`),y.inner.includes("*")&&(g=re())&&/^\.[^\\/.]+$/.test(g)&&($=y.close=`)${g})${_})`),y.prev.type==="bos"&&(l.negatedExtglob=!0)}x({type:"paren",extglob:!0,value:c,output:$}),ue("parens")};if(r.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(e)){let y=!1,$=e.replace(Gn,(g,_,I,q,M,Ie)=>q==="\\"?(y=!0,g):q==="?"?_?_+q+(M?N.repeat(M.length):""):Ie===0?H+(M?N.repeat(M.length):""):N.repeat(I.length):q==="."?R.repeat(I.length):q==="*"?_?_+q+(M?U:""):U:_?g:`\\${g}`);return y===!0&&(r.unescape===!0?$=$.replace(/\\/g,""):$=$.replace(/\\+/g,g=>g.length%2==0?"\\\\":g?"\\":"")),$===e&&r.contains===!0?(l.output=e,l):(l.output=Z.wrapOutput($,l,t),l)}for(;!K();){if(c=te(),c==="\0")continue;if(c==="\\"){let g=S();if(g==="/"&&r.bash!==!0||g==="."||g===";")continue;if(!g){c+="\\",x({type:"text",value:c});continue}let _=/^\\+/.exec(re()),I=0;if(_&&_[0].length>2&&(I=_[0].length,l.index+=I,I%2!=0&&(c+="\\")),r.unescape===!0?c=te():c+=te(),l.brackets===0){x({type:"text",value:c});continue}}if(l.brackets>0&&(c!=="]"||u.value==="["||u.value==="[^")){if(r.posix!==!1&&c===":"){let g=u.value.slice(1);if(g.includes("[")&&(u.posix=!0,g.includes(":"))){let _=u.value.lastIndexOf("["),I=u.value.slice(0,_),q=u.value.slice(_+2),M=Bn[q];if(M){u.value=I+M,l.backtrack=!0,te(),!a.output&&i.indexOf(u)===1&&(a.output=A);continue}}}(c==="["&&S()!==":"||c==="-"&&S()==="]")&&(c=`\\${c}`),c==="]"&&(u.value==="["||u.value==="[^")&&(c=`\\${c}`),r.posix===!0&&c==="!"&&u.value==="["&&(c="^"),u.value+=c,xe({value:c});continue}if(l.quotes===1&&c!=='"'){c=Z.escapeRegex(c),u.value+=c,xe({value:c});continue}if(c==='"'){l.quotes=l.quotes===1?0:1,r.keepQuotes===!0&&x({type:"text",value:c});continue}if(c==="("){be("parens"),x({type:"paren",value:c});continue}if(c===")"){if(l.parens===0&&r.strictBrackets===!0)throw new SyntaxError(fe("opening","("));let g=L[L.length-1];if(g&&l.parens===g.parens+1){Er(L.pop());continue}x({type:"paren",value:c,output:l.parens?")":"\\)"}),ue("parens");continue}if(c==="["){if(r.nobracket===!0||!re().includes("]")){if(r.nobracket!==!0&&r.strictBrackets===!0)throw new SyntaxError(fe("closing","]"));c=`\\${c}`}else be("brackets");x({type:"bracket",value:c});continue}if(c==="]"){if(r.nobracket===!0||u&&u.type==="bracket"&&u.value.length===1){x({type:"text",value:c,output:`\\${c}`});continue}if(l.brackets===0){if(r.strictBrackets===!0)throw new SyntaxError(fe("opening","["));x({type:"text",value:c,output:`\\${c}`});continue}ue("brackets");let g=u.value.slice(1);if(u.posix!==!0&&g[0]==="^"&&!g.includes("/")&&(c=`/${c}`),u.value+=c,xe({value:c}),r.literalBrackets===!1||Z.hasRegexChars(g))continue;let _=Z.escapeRegex(u.value);if(l.output=l.output.slice(0,-u.value.length),r.literalBrackets===!0){l.output+=_,u.value=_;continue}u.value=`(${o}${_}|${u.value})`,l.output+=u.value;continue}if(c==="{"&&r.nobrace!==!0){be("braces");let g={type:"brace",value:c,output:"(",outputIndex:l.output.length,tokensIndex:l.tokens.length};T.push(g),x(g);continue}if(c==="}"){let g=T[T.length-1];if(r.nobrace===!0||!g){x({type:"text",value:c,output:c});continue}let _=")";if(g.dots===!0){let I=i.slice(),q=[];for(let M=I.length-1;M>=0&&(i.pop(),I[M].type!=="brace");M--)I[M].type!=="dots"&&q.unshift(I[M].value);_=Fn(q,r),l.backtrack=!0}if(g.comma!==!0&&g.dots!==!0){let I=l.output.slice(0,g.outputIndex),q=l.tokens.slice(g.tokensIndex);g.value=g.output="\\{",c=_="\\}",l.output=I;for(let M of q)l.output+=M.output||M.value}x({type:"brace",value:c,output:_}),ue("braces"),T.pop();continue}if(c==="|"){L.length>0&&L[L.length-1].conditions++,x({type:"text",value:c});continue}if(c===","){let g=c,_=T[T.length-1];_&&oe[oe.length-1]==="braces"&&(_.comma=!0,g="|"),x({type:"comma",value:c,output:g});continue}if(c==="/"){if(u.type==="dot"&&l.index===l.start+1){l.start=l.index+1,l.consumed="",l.output="",i.pop(),u=a;continue}x({type:"slash",value:c,output:v});continue}if(c==="."){if(l.braces>0&&u.type==="dot"){u.value==="."&&(u.output=R);let g=T[T.length-1];u.type="dots",u.output+=c,u.value+=c,g.dots=!0;continue}if(l.braces+l.parens===0&&u.type!=="bos"&&u.type!=="slash"){x({type:"text",value:c,output:R});continue}x({type:"dot",value:c,output:R});continue}if(c==="?"){if(!(u&&u.value==="(")&&r.noextglob!==!0&&S()==="("&&S(2)!=="?"){Se("qmark",c);continue}if(u&&u.type==="paren"){let _=S(),I=c;if(_==="<"&&!Z.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(u.value==="("&&!/[!=<:]/.test(_)||_==="<"&&!/<([!=]|\w+>)/.test(re()))&&(I=`\\${c}`),x({type:"text",value:c,output:I});continue}if(r.dot!==!0&&(u.type==="slash"||u.type==="bos")){x({type:"qmark",value:c,output:ee});continue}x({type:"qmark",value:c,output:N});continue}if(c==="!"){if(r.noextglob!==!0&&S()==="("&&(S(2)!=="?"||!/[!=<:]/.test(S(3)))){Se("negate",c);continue}if(r.nonegate!==!0&&l.index===0){Cr();continue}}if(c==="+"){if(r.noextglob!==!0&&S()==="("&&S(2)!=="?"){Se("plus",c);continue}if(u&&u.value==="("||r.regex===!1){x({type:"plus",value:c,output:p});continue}if(u&&(u.type==="bracket"||u.type==="paren"||u.type==="brace")||l.parens>0){x({type:"plus",value:c});continue}x({type:"plus",value:p});continue}if(c==="@"){if(r.noextglob!==!0&&S()==="("&&S(2)!=="?"){x({type:"at",extglob:!0,value:c,output:""});continue}x({type:"text",value:c});continue}if(c!=="*"){(c==="$"||c==="^")&&(c=`\\${c}`);let g=Un.exec(re());g&&(c+=g[0],l.index+=g[0].length),x({type:"text",value:c});continue}if(u&&(u.type==="globstar"||u.star===!0)){u.type="star",u.star=!0,u.value+=c,u.output=U,l.backtrack=!0,l.globstar=!0,X(c);continue}let y=re();if(r.noextglob!==!0&&/^\([^?]/.test(y)){Se("star",c);continue}if(u.type==="star"){if(r.noglobstar===!0){X(c);continue}let g=u.prev,_=g.prev,I=g.type==="slash"||g.type==="bos",q=_&&(_.type==="star"||_.type==="globstar");if(r.bash===!0&&(!I||y[0]&&y[0]!=="/")){x({type:"star",value:c,output:""});continue}let M=l.braces>0&&(g.type==="comma"||g.type==="brace"),Ie=L.length&&(g.type==="pipe"||g.type==="paren");if(!I&&g.type!=="paren"&&!M&&!Ie){x({type:"star",value:c,output:""});continue}for(;y.slice(0,3)==="/**";){let ve=e[l.index+4];if(ve&&ve!=="/")break;y=y.slice(3),X("/**",3)}if(g.type==="bos"&&K()){u.type="globstar",u.value+=c,u.output=j(r),l.output=u.output,l.globstar=!0,X(c);continue}if(g.type==="slash"&&g.prev.type!=="bos"&&!q&&K()){l.output=l.output.slice(0,-(g.output+u.output).length),g.output=`(?:${g.output}`,u.type="globstar",u.output=j(r)+(r.strictSlashes?")":"|$)"),u.value+=c,l.globstar=!0,l.output+=g.output+u.output,X(c);continue}if(g.type==="slash"&&g.prev.type!=="bos"&&y[0]==="/"){let ve=y[1]!==void 0?"|$":"";l.output=l.output.slice(0,-(g.output+u.output).length),g.output=`(?:${g.output}`,u.type="globstar",u.output=`${j(r)}${v}|${v}${ve})`,u.value+=c,l.output+=g.output+u.output,l.globstar=!0,X(c+te()),x({type:"slash",value:"/",output:""});continue}if(g.type==="bos"&&y[0]==="/"){u.type="globstar",u.value+=c,u.output=`(?:^|${v}|${j(r)}${v})`,l.output=u.output,l.globstar=!0,X(c+te()),x({type:"slash",value:"/",output:""});continue}l.output=l.output.slice(0,-u.output.length),u.type="globstar",u.output=j(r),u.value+=c,l.output+=u.output,l.globstar=!0,X(c);continue}let $={type:"star",value:c,output:U};if(r.bash===!0){$.output=".*?",(u.type==="bos"||u.type==="slash")&&($.output=C+$.output),x($);continue}if(u&&(u.type==="bracket"||u.type==="paren")&&r.regex===!0){$.output=c,x($);continue}(l.index===l.start||u.type==="slash"||u.type==="dot")&&(u.type==="dot"?(l.output+=b,u.output+=b):r.dot===!0?(l.output+=k,u.output+=k):(l.output+=C,u.output+=C),S()!=="*"&&(l.output+=A,u.output+=A)),x($)}for(;l.brackets>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing","]"));l.output=Z.escapeLast(l.output,"["),ue("brackets")}for(;l.parens>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing",")"));l.output=Z.escapeLast(l.output,"("),ue("parens")}for(;l.braces>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing","}"));l.output=Z.escapeLast(l.output,"{"),ue("braces")}if(r.strictSlashes!==!0&&(u.type==="star"||u.type==="bracket")&&x({type:"maybe_slash",value:"",output:`${v}?`}),l.backtrack===!0){l.output="";for(let y of l.tokens)l.output+=y.output!=null?y.output:y.value,y.suffix&&(l.output+=y.suffix)}return l};tr.fastpaths=(e,t)=>{let r=w({},t),n=typeof r.maxLength=="number"?Math.min(Oe,r.maxLength):Oe,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);e=er[e]||e;let a=Z.isWindows(t),{DOT_LITERAL:i,SLASH_LITERAL:o,ONE_CHAR:h,DOTS_SLASH:d,NO_DOT:f,NO_DOTS:R,NO_DOTS_SLASH:p,STAR:v,START_ANCHOR:A}=Le.globChars(a),m=r.dot?R:f,E=r.dot?p:f,b=r.capture?"":"?:",k={negated:!1,prefix:""},N=r.bash===!0?".*?":v;r.capture&&(N=`(${N})`);let ee=C=>C.noglobstar===!0?N:`(${b}(?:(?!${A}${C.dot?d:i}).)*?)`,F=C=>{switch(C){case"*":return`${m}${h}${N}`;case".*":return`${i}${h}${N}`;case"*.*":return`${m}${N}${i}${h}${N}`;case"*/*":return`${m}${N}${o}${h}${E}${N}`;case"**":return m+ee(r);case"**/*":return`(?:${m}${ee(r)}${o})?${E}${h}${N}`;case"**/*.*":return`(?:${m}${ee(r)}${o})?${E}${N}${i}${h}${N}`;case"**/.*":return`(?:${m}${ee(r)}${o})?${i}${h}${N}`;default:{let H=/^(.*?)\.(\w+)$/.exec(C);if(!H)return;let U=F(H[1]);return U?U+i+H[2]:void 0}}},ie=Z.removePrefix(e,k),j=F(ie);return j&&r.strictSlashes!==!0&&(j+=`${o}?`),j};rr.exports=tr});var ar=G((hs,sr)=>{"use strict";var jn=W("path"),Kn=Jt(),Xe=nr(),ze=me(),qn=Ae(),Wn=e=>e&&typeof e=="object"&&!Array.isArray(e),D=(e,t,r=!1)=>{if(Array.isArray(e)){let f=e.map(p=>D(p,t,r));return p=>{for(let v of f){let A=v(p);if(A)return A}return!1}}let n=Wn(e)&&e.tokens&&e.input;if(e===""||typeof e!="string"&&!n)throw new TypeError("Expected pattern to be a non-empty string");let s=t||{},a=ze.isWindows(t),i=n?D.compileRe(e,t):D.makeRe(e,t,!1,!0),o=i.state;delete i.state;let h=()=>!1;if(s.ignore){let f=B(w({},t),{ignore:null,onMatch:null,onResult:null});h=D(s.ignore,f,r)}let d=(f,R=!1)=>{let{isMatch:p,match:v,output:A}=D.test(f,i,t,{glob:e,posix:a}),m={glob:e,state:o,regex:i,posix:a,input:f,output:A,match:v,isMatch:p};return typeof s.onResult=="function"&&s.onResult(m),p===!1?(m.isMatch=!1,R?m:!1):h(f)?(typeof s.onIgnore=="function"&&s.onIgnore(m),m.isMatch=!1,R?m:!1):(typeof s.onMatch=="function"&&s.onMatch(m),R?m:!0)};return r&&(d.state=o),d};D.test=(e,t,r,{glob:n,posix:s}={})=>{if(typeof e!="string")throw new TypeError("Expected input to be a string");if(e==="")return{isMatch:!1,output:""};let a=r||{},i=a.format||(s?ze.toPosixSlashes:null),o=e===n,h=o&&i?i(e):e;return o===!1&&(h=i?i(e):e,o=h===n),(o===!1||a.capture===!0)&&(a.matchBase===!0||a.basename===!0?o=D.matchBase(e,t,r,s):o=t.exec(h)),{isMatch:Boolean(o),match:o,output:h}};D.matchBase=(e,t,r,n=ze.isWindows(r))=>(t instanceof RegExp?t:D.makeRe(t,r)).test(jn.basename(e));D.isMatch=(e,t,r)=>D(t,r)(e);D.parse=(e,t)=>Array.isArray(e)?e.map(r=>D.parse(r,t)):Xe(e,B(w({},t),{fastpaths:!1}));D.scan=(e,t)=>Kn(e,t);D.compileRe=(e,t,r=!1,n=!1)=>{if(r===!0)return e.output;let s=t||{},a=s.contains?"":"^",i=s.contains?"":"$",o=`${a}(?:${e.output})${i}`;e&&e.negated===!0&&(o=`^(?!${o}).*$`);let h=D.toRegex(o,t);return n===!0&&(h.state=e),h};D.makeRe=(e,t={},r=!1,n=!1)=>{if(!e||typeof e!="string")throw new TypeError("Expected a non-empty string");let s={negated:!1,fastpaths:!0};return t.fastpaths!==!1&&(e[0]==="."||e[0]==="*")&&(s.output=Xe.fastpaths(e,t)),s.output||(s=Xe(e,t)),D.compileRe(s,t,r,n)};D.toRegex=(e,t)=>{try{let r=t||{};return new RegExp(e,r.flags||(r.nocase?"i":""))}catch(r){if(t&&t.debug===!0)throw r;return/$^/}};D.constants=qn;sr.exports=D});var or=G((gs,ir)=>{"use strict";ir.exports=ar()});var fr=G((ds,pr)=>{"use strict";var ur=W("util"),cr=Ut(),se=or(),Ze=me(),lr=e=>e===""||e==="./",O=(e,t,r)=>{t=[].concat(t),e=[].concat(e);let n=new Set,s=new Set,a=new Set,i=0,o=f=>{a.add(f.output),r&&r.onResult&&r.onResult(f)};for(let f=0;f!n.has(f));if(r&&d.length===0){if(r.failglob===!0)throw new Error(`No matches found for "${t.join(", ")}"`);if(r.nonull===!0||r.nullglob===!0)return r.unescape?t.map(f=>f.replace(/\\/g,"")):t}return d};O.match=O;O.matcher=(e,t)=>se(e,t);O.isMatch=(e,t,r)=>se(t,r)(e);O.any=O.isMatch;O.not=(e,t,r={})=>{t=[].concat(t).map(String);let n=new Set,s=[],a=o=>{r.onResult&&r.onResult(o),s.push(o.output)},i=O(e,t,B(w({},r),{onResult:a}));for(let o of s)i.includes(o)||n.add(o);return[...n]};O.contains=(e,t,r)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${ur.inspect(e)}"`);if(Array.isArray(t))return t.some(n=>O.contains(e,n,r));if(typeof t=="string"){if(lr(e)||lr(t))return!1;if(e.includes(t)||e.startsWith("./")&&e.slice(2).includes(t))return!0}return O.isMatch(e,t,B(w({},r),{contains:!0}))};O.matchKeys=(e,t,r)=>{if(!Ze.isObject(e))throw new TypeError("Expected the first argument to be an object");let n=O(Object.keys(e),t,r),s={};for(let a of n)s[a]=e[a];return s};O.some=(e,t,r)=>{let n=[].concat(e);for(let s of[].concat(t)){let a=se(String(s),r);if(n.some(i=>a(i)))return!0}return!1};O.every=(e,t,r)=>{let n=[].concat(e);for(let s of[].concat(t)){let a=se(String(s),r);if(!n.every(i=>a(i)))return!1}return!0};O.all=(e,t,r)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${ur.inspect(e)}"`);return[].concat(t).every(n=>se(n,r)(e))};O.capture=(e,t,r)=>{let n=Ze.isWindows(r),a=se.makeRe(String(e),B(w({},r),{capture:!0})).exec(n?Ze.toPosixSlashes(t):t);if(a)return a.slice(1).map(i=>i===void 0?"":i)};O.makeRe=(...e)=>se.makeRe(...e);O.scan=(...e)=>se.scan(...e);O.parse=(e,t)=>{let r=[];for(let n of[].concat(e||[]))for(let s of cr(String(n),t))r.push(se.parse(s,t));return r};O.braces=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");return t&&t.nobrace===!0||!/\{.*\}/.test(e)?[e]:cr(e,t)};O.braceExpand=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");return O.braces(e,B(w({},t),{expand:!0}))};pr.exports=O});var Vn={};$r(Vn,{default:()=>Zn});var ke=J(W("@yarnpkg/cli")),P=J(W("@yarnpkg/core")),V=J(W("clipanion")),et=J(fr()),mr=J(W("path")),Ne=J(W("semver")),de=J(W("typanion"));var he=J(W("@yarnpkg/core")),yr=J(W("@yarnpkg/plugin-essentials"));var Ee=J(W("semver")),hr=Boolean;function Qn(e){var s;let[t,r,n]=(s=e.match(/(github|bitbucket|gitlab):(.+)/))!=null?s:[];return r?`https://${r}.${r==="bitbucket"?"org":"com"}/${n}`:`https://github.com/${e}`}function gr(e){let{homepage:t,repository:r}=e.raw;return t||(typeof r=="string"?Qn(r):r==null?void 0:r.url)}function dr(e,t){return Ee.default.parse(t).prerelease.length?Ee.default.lt(e,t):Ee.default.lt(Ee.default.coerce(e),t)}var Ve=class{constructor(t,r,n,s){this.configuration=t;this.project=r;this.workspace=n;this.cache=s}async fetch({descriptor:t,includeRange:r,includeURL:n,pkg:s}){let[a,i,o]=await Promise.all([this.suggest(s,"latest"),r?this.suggest(s,t.range):Promise.resolve(),n?this.fetchURL(s):Promise.resolve()]);if(!a){let h=he.structUtils.prettyIdent(this.configuration,s);throw new Error(`Could not fetch candidate for ${h}.`)}return{latest:a.range,range:i==null?void 0:i.range,url:o}}suggest(t,r){return yr.suggestUtils.fetchDescriptorFrom(t,r,{cache:this.cache,preserveModifier:!1,project:this.project,workspace:this.workspace})}async fetchURL(t){var a;let r=this.configuration.makeFetcher(),n=await r.fetch(t,{cache:this.cache,checksums:this.project.storedChecksums,fetcher:r,project:this.project,report:new he.ThrowReport,skipIntegrityCheck:!0}),s;try{s=await he.Manifest.find(n.prefixPath,{baseFs:n.packageFs})}finally{(a=n.releaseFs)==null||a.call(n)}return gr(s)}};var ge=J(W("@yarnpkg/core")),Xn=/^([0-9]+\.)([0-9]+\.)(.+)$/,Rr=["name","current","range","latest","workspace","type","url"],Ye=class{constructor(t,r,n,s){this.report=t;this.configuration=r;this.dependencies=n;this.extraColumns=s;this.sizes=null;this.headers={current:"Current",latest:"Latest",name:"Package",range:"Range",type:"Package Type",url:"URL",workspace:"Workspace"}}print(){this.sizes=this.getColumnSizes(),this.printHeader(),this.dependencies.forEach(t=>{var s,a;let r=this.getDiffColor(t.severity.latest),n=this.getDiffColor(t.severity.range);this.printRow({current:t.current.padEnd(this.sizes.current),latest:this.formatVersion(t,"latest",r),name:this.applyColor(t.name.padEnd(this.sizes.name),r),range:this.formatVersion(t,"range",n),type:t.type.padEnd(this.sizes.type),url:(s=t.url)==null?void 0:s.padEnd(this.sizes.url),workspace:(a=t.workspace)==null?void 0:a.padEnd(this.sizes.workspace)})})}applyColor(t,r){return r?ge.formatUtils.pretty(this.configuration,t,r):t}formatVersion(t,r,n){var d;let s=(d=t[r])==null?void 0:d.padEnd(this.sizes[r]);if(!s)return;let a=s.match(Xn);if(!a||!n)return s;let i=["red","yellow","green"].indexOf(n)+1,o=a.slice(1,i).join(""),h=a.slice(i).join("");return o+ge.formatUtils.pretty(this.configuration,this.applyColor(h,n),"bold")}getDiffColor(t){return t?{major:"red",minor:"yellow",patch:"green"}[t]:null}getColumnSizes(){let t=Rr.reduce((r,n)=>B(w({},r),{[n]:this.headers[n].length}),{});for(let r of this.dependencies)for(let[n,s]of Object.entries(r)){let a=t[n],i=(s||"").length;t[n]=a>i?a:i}return t}formatColumnHeader(t){return ge.formatUtils.pretty(this.configuration,this.headers[t].padEnd(this.sizes[t]),"bold")}printHeader(){this.printRow({current:this.formatColumnHeader("current"),latest:this.formatColumnHeader("latest"),name:this.formatColumnHeader("name"),range:this.formatColumnHeader("range"),type:this.formatColumnHeader("type"),url:this.formatColumnHeader("url"),workspace:this.formatColumnHeader("workspace")})}printRow(t){let r=Rr.filter(n=>{var s;return(s=this.extraColumns[n])!=null?s:!0}).map(n=>t[n]).join(" ").trim();this.report.reportInfo(ge.MessageName.UNNAMED,r)}};var Je=["dependencies","devDependencies"],Ar=["major","minor","patch"];var _e=class extends ke.BaseCommand{constructor(){super(...arguments);this.patterns=V.Option.Rest();this.workspace=V.Option.Array("-w,--workspace",{description:"Only search for dependencies in the specified workspaces. If no workspaces are specified, only searches for outdated dependencies in the current workspace.",validator:de.default.isArray(de.default.isString())});this.check=V.Option.Boolean("-c,--check",!1,{description:"Exit with exit code 1 when outdated dependencies are found"});this.json=V.Option.Boolean("--json",!1,{description:"Format the output as JSON"});this.severity=V.Option.Array("-s,--severity",{description:"Filter results based on the severity of the update",validator:de.default.isArray(de.default.isEnum(Ar))});this.type=V.Option.String("-t,--type",{description:"Filter results based on the dependency type",validator:de.default.isEnum(Je)});this.includeURL=V.Option.Boolean("--url",!1,{description:"Include the homepage URL of each package in the output"});this.includeRange=V.Option.Boolean("--range",!1,{description:"Include the latest version of the package which satisfies the current range specified in the manifest."})}async execute(){let{cache:t,configuration:r,project:n,workspace:s}=await this.loadProject(),a=new Ve(r,n,s,t),i=this.getWorkspaces(n),o=this.getDependencies(r,i);if(this.json){let f=(await this.getOutdatedDependencies(n,a,o)).map(R=>B(w({},R),{severity:R.severity.latest}));this.context.stdout.write(JSON.stringify(f)+` 8 | `);return}return(await P.StreamReport.start({configuration:r,stdout:this.context.stdout},async d=>{await this.checkOutdatedDependencies(r,n,o,a,d)})).exitCode()}async checkOutdatedDependencies(t,r,n,s,a){let i=null;await a.startTimerPromise("Checking for outdated dependencies",async()=>{let o=n.length,h=P.StreamReport.progressViaCounter(o);a.reportProgress(h),i=await this.getOutdatedDependencies(r,s,n,h)}),a.reportSeparator(),i.length?(new Ye(a,t,i,{range:this.includeRange,url:this.includeURL,workspace:this.includeWorkspace(r)}).print(),a.reportSeparator(),this.printOutdatedCount(a,i.length)):this.printUpToDate(t,a)}async loadProject(){let t=await P.Configuration.find(this.context.cwd,this.context.plugins),[r,{project:n,workspace:s}]=await Promise.all([P.Cache.find(t),P.Project.find(t,this.context.cwd)]);if(await n.restoreInstallState(),!s)throw new ke.WorkspaceRequiredError(n.cwd,this.context.cwd);return{cache:r,configuration:t,project:n,workspace:s}}getWorkspaces(t){let r=this.workspace;return r?r[0]==="."?t.workspaces.filter(n=>n.cwd===this.context.cwd):t.workspaces.filter(n=>{let s=[...r,...r.map(a=>mr.default.join(this.context.cwd,a))];return et.default.some([this.getWorkspaceName(n),n.cwd],s)}):t.workspaces}includeWorkspace(t){return t.workspaces.length>1}get dependencyTypes(){return this.type?[this.type]:Je}getDependencies(t,r){let n=[];for(let a of r){let{anchoredLocator:i,project:o}=a,h=o.storedPackages.get(i.locatorHash);h||this.throw(t,i);for(let d of this.dependencyTypes)for(let f of a.manifest[d].values()){let{range:R}=f;if(R.includes(":")&&!/(npm|patch):/.test(R))continue;let p=h.dependencies.get(f.identHash);p||this.throw(t,f);let v=o.storedResolutions.get(p.descriptorHash);v||this.throw(t,p);let A=o.storedPackages.get(v);A||this.throw(t,p),!a.project.tryWorkspaceByLocator(A)&&(A.reference.includes("github.com")||n.push({dependencyType:d,descriptor:f,name:P.structUtils.stringifyIdent(f),pkg:A,workspace:a}))}}if(!this.patterns.length)return n;let s=n.filter(({name:a})=>et.default.isMatch(a,this.patterns));if(!s.length)throw new V.UsageError(`Pattern ${P.formatUtils.prettyList(t,this.patterns,P.FormatType.CODE)} doesn't match any packages referenced by any workspace`);return s}throw(t,r){let n=P.structUtils.prettyIdent(t,r);throw new Error(`Package for ${n} not found in the project`)}getSeverity(t,r){let n=Ne.default.coerce(t),s=Ne.default.coerce(r);return Ne.default.eq(n,s)?null:n.major===0||s.major>n.major?"major":s.minor>n.minor?"minor":"patch"}async getOutdatedDependencies(t,r,n,s){let a=n.map(async({dependencyType:i,descriptor:o,name:h,pkg:d,workspace:f})=>{let{latest:R,range:p,url:v}=await r.fetch({descriptor:o,includeRange:this.includeRange,includeURL:this.includeURL,pkg:d});if(s==null||s.tick(),dr(d.version,R))return{current:d.version,latest:R,name:h,range:p,severity:{latest:this.getSeverity(d.version,R),range:p?this.getSeverity(d.version,p):null},type:i,url:v,workspace:this.includeWorkspace(t)?this.getWorkspaceName(f):void 0}});return(await Promise.all(a)).filter(hr).filter(i=>{var o,h;return(h=(o=this.severity)==null?void 0:o.includes(i.severity.latest))!=null?h:!0}).sort((i,o)=>i.name.localeCompare(o.name))}getWorkspaceName(t){return t.manifest.name?P.structUtils.stringifyIdent(t.manifest.name):t.computeCandidateName()}printOutdatedCount(t,r){let n=[P.MessageName.UNNAMED,r===1?"1 dependency is out of date":`${r} dependencies are out of date`];this.check?t.reportError(...n):t.reportWarning(...n)}printUpToDate(t,r){let n="\u2728 All your dependencies are up to date!";r.reportInfo(P.MessageName.UNNAMED,P.formatUtils.pretty(t,n,"green"))}};_e.paths=[["outdated"]],_e.usage=V.Command.Usage({description:"view outdated dependencies",details:` 9 | This command finds outdated dependencies in a project and prints the result in a table or JSON format. 10 | 11 | This command accepts glob patterns as arguments to filter the output. Make sure to escape the patterns, to prevent your own shell from trying to expand them. 12 | `,examples:[["View outdated dependencies","yarn outdated"],["View outdated dependencies with the `@babel` scope","yarn outdated '@babel/*'"],["Filter results to only include devDependencies","yarn outdated --type devDependencies"],["Filter results to only include major version updates","yarn outdated --severity major"]]});var zn={commands:[_e]},Zn=zn;return Vn;})(); 13 | /*! 14 | * fill-range 15 | * 16 | * Copyright (c) 2014-present, Jon Schlinkert. 17 | * Licensed under the MIT License. 18 | */ 19 | /*! 20 | * is-number 21 | * 22 | * Copyright (c) 2014-present, Jon Schlinkert. 23 | * Released under the MIT License. 24 | */ 25 | /*! 26 | * to-regex-range 27 | * 28 | * Copyright (c) 2015-present, Jon Schlinkert. 29 | * Released under the MIT License. 30 | */ 31 | return plugin; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /.yarn/releases/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2016-present, Yarn Contributors. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /.yarn/sdks/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2016-present, Yarn Contributors. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /.yarn/sdks/integrations.yml: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by @yarnpkg/sdks. 2 | # Manual changes might be lost! 3 | 4 | integrations: 5 | - vscode 6 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/bin/tsc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript/bin/tsc 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real typescript/bin/tsc your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsc`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/bin/tsserver: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript/bin/tsserver 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real typescript/bin/tsserver your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsserver`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/tsc.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript/lib/tsc.js 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real typescript/lib/tsc.js your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`typescript/lib/tsc.js`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/tsserver.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript/lib/tsserver.js 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | const moduleWrapper = exports => { 32 | return wrapWithUserWrapper(moduleWrapperFn(exports)); 33 | }; 34 | 35 | const moduleWrapperFn = tsserver => { 36 | if (!process.versions.pnp) { 37 | return tsserver; 38 | } 39 | 40 | const {isAbsolute} = require(`path`); 41 | const pnpApi = require(`pnpapi`); 42 | 43 | const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); 44 | const isPortal = str => str.startsWith("portal:/"); 45 | const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); 46 | 47 | const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { 48 | return `${locator.name}@${locator.reference}`; 49 | })); 50 | 51 | // VSCode sends the zip paths to TS using the "zip://" prefix, that TS 52 | // doesn't understand. This layer makes sure to remove the protocol 53 | // before forwarding it to TS, and to add it back on all returned paths. 54 | 55 | function toEditorPath(str) { 56 | // We add the `zip:` prefix to both `.zip/` paths and virtual paths 57 | if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { 58 | // We also take the opportunity to turn virtual paths into physical ones; 59 | // this makes it much easier to work with workspaces that list peer 60 | // dependencies, since otherwise Ctrl+Click would bring us to the virtual 61 | // file instances instead of the real ones. 62 | // 63 | // We only do this to modules owned by the the dependency tree roots. 64 | // This avoids breaking the resolution when jumping inside a vendor 65 | // with peer dep (otherwise jumping into react-dom would show resolution 66 | // errors on react). 67 | // 68 | const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; 69 | if (resolved) { 70 | const locator = pnpApi.findPackageLocator(resolved); 71 | if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { 72 | str = resolved; 73 | } 74 | } 75 | 76 | str = normalize(str); 77 | 78 | if (str.match(/\.zip\//)) { 79 | switch (hostInfo) { 80 | // Absolute VSCode `Uri.fsPath`s need to start with a slash. 81 | // VSCode only adds it automatically for supported schemes, 82 | // so we have to do it manually for the `zip` scheme. 83 | // The path needs to start with a caret otherwise VSCode doesn't handle the protocol 84 | // 85 | // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 86 | // 87 | // 2021-10-08: VSCode changed the format in 1.61. 88 | // Before | ^zip:/c:/foo/bar.zip/package.json 89 | // After | ^/zip//c:/foo/bar.zip/package.json 90 | // 91 | // 2022-04-06: VSCode changed the format in 1.66. 92 | // Before | ^/zip//c:/foo/bar.zip/package.json 93 | // After | ^/zip/c:/foo/bar.zip/package.json 94 | // 95 | // 2022-05-06: VSCode changed the format in 1.68 96 | // Before | ^/zip/c:/foo/bar.zip/package.json 97 | // After | ^/zip//c:/foo/bar.zip/package.json 98 | // 99 | case `vscode <1.61`: { 100 | str = `^zip:${str}`; 101 | } break; 102 | 103 | case `vscode <1.66`: { 104 | str = `^/zip/${str}`; 105 | } break; 106 | 107 | case `vscode <1.68`: { 108 | str = `^/zip${str}`; 109 | } break; 110 | 111 | case `vscode`: { 112 | str = `^/zip/${str}`; 113 | } break; 114 | 115 | // To make "go to definition" work, 116 | // We have to resolve the actual file system path from virtual path 117 | // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) 118 | case `coc-nvim`: { 119 | str = normalize(resolved).replace(/\.zip\//, `.zip::`); 120 | str = resolve(`zipfile:${str}`); 121 | } break; 122 | 123 | // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) 124 | // We have to resolve the actual file system path from virtual path, 125 | // everything else is up to neovim 126 | case `neovim`: { 127 | str = normalize(resolved).replace(/\.zip\//, `.zip::`); 128 | str = `zipfile://${str}`; 129 | } break; 130 | 131 | default: { 132 | str = `zip:${str}`; 133 | } break; 134 | } 135 | } else { 136 | str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); 137 | } 138 | } 139 | 140 | return str; 141 | } 142 | 143 | function fromEditorPath(str) { 144 | switch (hostInfo) { 145 | case `coc-nvim`: { 146 | str = str.replace(/\.zip::/, `.zip/`); 147 | // The path for coc-nvim is in format of //zipfile://.yarn/... 148 | // So in order to convert it back, we use .* to match all the thing 149 | // before `zipfile:` 150 | return process.platform === `win32` 151 | ? str.replace(/^.*zipfile:\//, ``) 152 | : str.replace(/^.*zipfile:/, ``); 153 | } break; 154 | 155 | case `neovim`: { 156 | str = str.replace(/\.zip::/, `.zip/`); 157 | // The path for neovim is in format of zipfile:////.yarn/... 158 | return str.replace(/^zipfile:\/\//, ``); 159 | } break; 160 | 161 | case `vscode`: 162 | default: { 163 | return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) 164 | } break; 165 | } 166 | } 167 | 168 | // Force enable 'allowLocalPluginLoads' 169 | // TypeScript tries to resolve plugins using a path relative to itself 170 | // which doesn't work when using the global cache 171 | // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 172 | // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but 173 | // TypeScript already does local loads and if this code is running the user trusts the workspace 174 | // https://github.com/microsoft/vscode/issues/45856 175 | const ConfiguredProject = tsserver.server.ConfiguredProject; 176 | const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; 177 | ConfiguredProject.prototype.enablePluginsWithOptions = function() { 178 | this.projectService.allowLocalPluginLoads = true; 179 | return originalEnablePluginsWithOptions.apply(this, arguments); 180 | }; 181 | 182 | // And here is the point where we hijack the VSCode <-> TS communications 183 | // by adding ourselves in the middle. We locate everything that looks 184 | // like an absolute path of ours and normalize it. 185 | 186 | const Session = tsserver.server.Session; 187 | const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; 188 | let hostInfo = `unknown`; 189 | 190 | Object.assign(Session.prototype, { 191 | onMessage(/** @type {string | object} */ message) { 192 | const isStringMessage = typeof message === 'string'; 193 | const parsedMessage = isStringMessage ? JSON.parse(message) : message; 194 | 195 | if ( 196 | parsedMessage != null && 197 | typeof parsedMessage === `object` && 198 | parsedMessage.arguments && 199 | typeof parsedMessage.arguments.hostInfo === `string` 200 | ) { 201 | hostInfo = parsedMessage.arguments.hostInfo; 202 | if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { 203 | const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( 204 | // The RegExp from https://semver.org/ but without the caret at the start 205 | /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ 206 | ) ?? []).map(Number) 207 | 208 | if (major === 1) { 209 | if (minor < 61) { 210 | hostInfo += ` <1.61`; 211 | } else if (minor < 66) { 212 | hostInfo += ` <1.66`; 213 | } else if (minor < 68) { 214 | hostInfo += ` <1.68`; 215 | } 216 | } 217 | } 218 | } 219 | 220 | const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { 221 | return typeof value === 'string' ? fromEditorPath(value) : value; 222 | }); 223 | 224 | return originalOnMessage.call( 225 | this, 226 | isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) 227 | ); 228 | }, 229 | 230 | send(/** @type {any} */ msg) { 231 | return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { 232 | return typeof value === `string` ? toEditorPath(value) : value; 233 | }))); 234 | } 235 | }); 236 | 237 | return tsserver; 238 | }; 239 | 240 | const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10)); 241 | // In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well. 242 | // Ref https://github.com/microsoft/TypeScript/pull/55326 243 | if (major > 5 || (major === 5 && minor >= 5)) { 244 | moduleWrapper(absRequire(`typescript`)); 245 | } 246 | 247 | // Defer to the real typescript/lib/tsserver.js your application uses 248 | module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`)); 249 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/tsserverlibrary.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript/lib/tsserverlibrary.js 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | const moduleWrapper = exports => { 32 | return wrapWithUserWrapper(moduleWrapperFn(exports)); 33 | }; 34 | 35 | const moduleWrapperFn = tsserver => { 36 | if (!process.versions.pnp) { 37 | return tsserver; 38 | } 39 | 40 | const {isAbsolute} = require(`path`); 41 | const pnpApi = require(`pnpapi`); 42 | 43 | const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); 44 | const isPortal = str => str.startsWith("portal:/"); 45 | const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); 46 | 47 | const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { 48 | return `${locator.name}@${locator.reference}`; 49 | })); 50 | 51 | // VSCode sends the zip paths to TS using the "zip://" prefix, that TS 52 | // doesn't understand. This layer makes sure to remove the protocol 53 | // before forwarding it to TS, and to add it back on all returned paths. 54 | 55 | function toEditorPath(str) { 56 | // We add the `zip:` prefix to both `.zip/` paths and virtual paths 57 | if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { 58 | // We also take the opportunity to turn virtual paths into physical ones; 59 | // this makes it much easier to work with workspaces that list peer 60 | // dependencies, since otherwise Ctrl+Click would bring us to the virtual 61 | // file instances instead of the real ones. 62 | // 63 | // We only do this to modules owned by the the dependency tree roots. 64 | // This avoids breaking the resolution when jumping inside a vendor 65 | // with peer dep (otherwise jumping into react-dom would show resolution 66 | // errors on react). 67 | // 68 | const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; 69 | if (resolved) { 70 | const locator = pnpApi.findPackageLocator(resolved); 71 | if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { 72 | str = resolved; 73 | } 74 | } 75 | 76 | str = normalize(str); 77 | 78 | if (str.match(/\.zip\//)) { 79 | switch (hostInfo) { 80 | // Absolute VSCode `Uri.fsPath`s need to start with a slash. 81 | // VSCode only adds it automatically for supported schemes, 82 | // so we have to do it manually for the `zip` scheme. 83 | // The path needs to start with a caret otherwise VSCode doesn't handle the protocol 84 | // 85 | // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 86 | // 87 | // 2021-10-08: VSCode changed the format in 1.61. 88 | // Before | ^zip:/c:/foo/bar.zip/package.json 89 | // After | ^/zip//c:/foo/bar.zip/package.json 90 | // 91 | // 2022-04-06: VSCode changed the format in 1.66. 92 | // Before | ^/zip//c:/foo/bar.zip/package.json 93 | // After | ^/zip/c:/foo/bar.zip/package.json 94 | // 95 | // 2022-05-06: VSCode changed the format in 1.68 96 | // Before | ^/zip/c:/foo/bar.zip/package.json 97 | // After | ^/zip//c:/foo/bar.zip/package.json 98 | // 99 | case `vscode <1.61`: { 100 | str = `^zip:${str}`; 101 | } break; 102 | 103 | case `vscode <1.66`: { 104 | str = `^/zip/${str}`; 105 | } break; 106 | 107 | case `vscode <1.68`: { 108 | str = `^/zip${str}`; 109 | } break; 110 | 111 | case `vscode`: { 112 | str = `^/zip/${str}`; 113 | } break; 114 | 115 | // To make "go to definition" work, 116 | // We have to resolve the actual file system path from virtual path 117 | // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) 118 | case `coc-nvim`: { 119 | str = normalize(resolved).replace(/\.zip\//, `.zip::`); 120 | str = resolve(`zipfile:${str}`); 121 | } break; 122 | 123 | // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) 124 | // We have to resolve the actual file system path from virtual path, 125 | // everything else is up to neovim 126 | case `neovim`: { 127 | str = normalize(resolved).replace(/\.zip\//, `.zip::`); 128 | str = `zipfile://${str}`; 129 | } break; 130 | 131 | default: { 132 | str = `zip:${str}`; 133 | } break; 134 | } 135 | } else { 136 | str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); 137 | } 138 | } 139 | 140 | return str; 141 | } 142 | 143 | function fromEditorPath(str) { 144 | switch (hostInfo) { 145 | case `coc-nvim`: { 146 | str = str.replace(/\.zip::/, `.zip/`); 147 | // The path for coc-nvim is in format of //zipfile://.yarn/... 148 | // So in order to convert it back, we use .* to match all the thing 149 | // before `zipfile:` 150 | return process.platform === `win32` 151 | ? str.replace(/^.*zipfile:\//, ``) 152 | : str.replace(/^.*zipfile:/, ``); 153 | } break; 154 | 155 | case `neovim`: { 156 | str = str.replace(/\.zip::/, `.zip/`); 157 | // The path for neovim is in format of zipfile:////.yarn/... 158 | return str.replace(/^zipfile:\/\//, ``); 159 | } break; 160 | 161 | case `vscode`: 162 | default: { 163 | return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) 164 | } break; 165 | } 166 | } 167 | 168 | // Force enable 'allowLocalPluginLoads' 169 | // TypeScript tries to resolve plugins using a path relative to itself 170 | // which doesn't work when using the global cache 171 | // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 172 | // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but 173 | // TypeScript already does local loads and if this code is running the user trusts the workspace 174 | // https://github.com/microsoft/vscode/issues/45856 175 | const ConfiguredProject = tsserver.server.ConfiguredProject; 176 | const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; 177 | ConfiguredProject.prototype.enablePluginsWithOptions = function() { 178 | this.projectService.allowLocalPluginLoads = true; 179 | return originalEnablePluginsWithOptions.apply(this, arguments); 180 | }; 181 | 182 | // And here is the point where we hijack the VSCode <-> TS communications 183 | // by adding ourselves in the middle. We locate everything that looks 184 | // like an absolute path of ours and normalize it. 185 | 186 | const Session = tsserver.server.Session; 187 | const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; 188 | let hostInfo = `unknown`; 189 | 190 | Object.assign(Session.prototype, { 191 | onMessage(/** @type {string | object} */ message) { 192 | const isStringMessage = typeof message === 'string'; 193 | const parsedMessage = isStringMessage ? JSON.parse(message) : message; 194 | 195 | if ( 196 | parsedMessage != null && 197 | typeof parsedMessage === `object` && 198 | parsedMessage.arguments && 199 | typeof parsedMessage.arguments.hostInfo === `string` 200 | ) { 201 | hostInfo = parsedMessage.arguments.hostInfo; 202 | if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { 203 | const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( 204 | // The RegExp from https://semver.org/ but without the caret at the start 205 | /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ 206 | ) ?? []).map(Number) 207 | 208 | if (major === 1) { 209 | if (minor < 61) { 210 | hostInfo += ` <1.61`; 211 | } else if (minor < 66) { 212 | hostInfo += ` <1.66`; 213 | } else if (minor < 68) { 214 | hostInfo += ` <1.68`; 215 | } 216 | } 217 | } 218 | } 219 | 220 | const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { 221 | return typeof value === 'string' ? fromEditorPath(value) : value; 222 | }); 223 | 224 | return originalOnMessage.call( 225 | this, 226 | isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) 227 | ); 228 | }, 229 | 230 | send(/** @type {any} */ msg) { 231 | return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { 232 | return typeof value === `string` ? toEditorPath(value) : value; 233 | }))); 234 | } 235 | }); 236 | 237 | return tsserver; 238 | }; 239 | 240 | const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10)); 241 | // In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well. 242 | // Ref https://github.com/microsoft/TypeScript/pull/55326 243 | if (major > 5 || (major === 5 && minor >= 5)) { 244 | moduleWrapper(absRequire(`typescript`)); 245 | } 246 | 247 | // Defer to the real typescript/lib/tsserverlibrary.js your application uses 248 | module.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`)); 249 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/lib/typescript.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {existsSync} = require(`fs`); 4 | const {createRequire, register} = require(`module`); 5 | const {resolve} = require(`path`); 6 | const {pathToFileURL} = require(`url`); 7 | 8 | const relPnpApiPath = "../../../../.pnp.cjs"; 9 | 10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath); 11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); 12 | const absRequire = createRequire(absPnpApiPath); 13 | 14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); 15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); 16 | 17 | if (existsSync(absPnpApiPath)) { 18 | if (!process.versions.pnp) { 19 | // Setup the environment to be able to require typescript 20 | require(absPnpApiPath).setup(); 21 | if (isPnpLoaderEnabled && register) { 22 | register(pathToFileURL(absPnpLoaderPath)); 23 | } 24 | } 25 | } 26 | 27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath) 28 | ? exports => absRequire(absUserWrapperPath)(exports) 29 | : exports => exports; 30 | 31 | // Defer to the real typescript your application uses 32 | module.exports = wrapWithUserWrapper(absRequire(`typescript`)); 33 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript", 3 | "version": "5.5.4-sdk", 4 | "main": "./lib/typescript.js", 5 | "type": "commonjs", 6 | "bin": { 7 | "tsc": "./bin/tsc", 8 | "tsserver": "./bin/tsserver" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | enableGlobalCache: true 2 | 3 | plugins: 4 | - checksum: 5e73a1acbb9741fce1e8335e243c9480ea2107b9b4b65ed7643785ddea9e3019aee254a92a853b1cd71023b16fff5b7d3afd5256fe57cd35a54f8785b8c30281 5 | path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs 6 | spec: "https://go.mskelton.dev/yarn-outdated/v4" 7 | 8 | yarnPath: .yarn/releases/yarn-4.4.1.cjs 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vscode-packaging 2 | 3 | This is the source code repository for the `packaging` 4 | VS Code extension. 5 | 6 | This document is for **contributors,** not for users of this 7 | extension. 8 | For **user documentation,** see: [extension/README.md](./extension/README.md) 9 | For **license information,** see the bottom of this document. 10 | 11 | ## About the extension 12 | 13 | For a list of features and details, see the user documentation: 14 | [extension/README.md](./extension/README.md) 15 | 16 | ## Requirements for contributing 17 | 18 | Working on this VS Code extension requires the following programs to 19 | be installed on your system: 20 | 21 | - `yarn` (required) 22 | - `nvm` (recommended) 23 | 24 | ## Preparing your session 25 | 26 | To prepare your session, `cd` to the project root directory, then 27 | run `nvm use`. 28 | 29 | ## Installing dependencies 30 | 31 | To install dependencies, run: `yarn install` 32 | 33 | If that fails, consult the _Maintenance_ section. 34 | 35 | ## Building the extension 36 | 37 | To build the extension, run: `yarn package` 38 | 39 | Unlike `vsce package`, running `yarn package` will work around issue 40 | [microsoft/vscode-vsce#517](https://github.com/microsoft/vscode-vsce/issues/517). 41 | Use `yarn package` as long as the issue is unresolved. 42 | 43 | ## Publishing the extension 44 | 45 | Publishing the extension has several steps: 46 | 47 | 1. Merge the contributions. 48 | 2. Choose a target version number. 49 | 3. Publish to the Marketplace. (This modifies `extension/package.json`.) 50 | 4. Publish to the Open VSX Registry. 51 | 5. Create a Git commit, Git tag, GitHub prerelease and GitHub PR. 52 | 53 | ### Merging the contributions 54 | 55 | Make sure that all the contributions you’re going to have in the 56 | release have been merged to the `main` branch. 57 | 58 | ### Choosing a target version number 59 | 60 | With all contributions merged into `main`, choose a target version 61 | number. 62 | [The VS Code folks recommend](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#prerelease-extensions) 63 | the following numbering scheme: 64 | 65 | - `major.ODD_NUMBER.patch` (e.g. 1.1.0) for **pre-release** versions; and 66 | - `major.EVEN_NUMBER.patch` (e.g. 1.2.0) for **release** versions. 67 | 68 | ### Publishing to the Marketplace 69 | 70 | 1. Check out the `main` branch and make sure it is pristine. 71 | 72 | 2. Decide on a new version number under which to publish the package. 73 | 74 | 3. Edit the `extension/share/dist/package.json` manifest to reflect 75 | the new version number. 76 | 77 | 4. Run: `yarn package` 78 | 79 | 5. If necessary, run: `yarn workspace extension login` 80 | 81 | 6. Run: `yarn workspace extension publish-vsce [--pre-release]` 82 | 83 | The final `yarn […] publish-vsce` command packages and publishes the 84 | extension to the VS Code Extension Marketplace. 85 | 86 | ### Publishing to the Open VSX Registry 87 | 88 | Follow these steps to publish the extension to the Open VSX Registry: 89 | 90 | 1. Set the `OVSX_PAT` environment variable to your personal access 91 | token. 92 | 93 | For example, if you’re on Bash and you have your token in 94 | 1Password, you could run the following command line: 95 | 96 | ```bash 97 | read -r OVSX_PAT < <( 98 | op item get 'Open VSX Registry' --fields password 99 | ) && export OVSX_PAT 100 | ``` 101 | 102 | 2. Make sure you have published the extension to the VS Code 103 | Extension Marketplace. This ensures that the version number has 104 | been updated. 105 | 106 | 3. Run `yarn package` to generate a `.vsix` package. 107 | 108 | 4. Run the `yarn […] ovsx publish` command with the correct 109 | `extension/dist/[…].vsix` file as the sole argument. 110 | Example in Bash: 111 | 112 | ```bash 113 | yarn workspace extension ovsx publish "dist/packaging-$(jq -r .version extension/share/dist/package.json).vsix" 114 | ``` 115 | 116 | ### Committing, tagging and creating a GitHub prerelease and PR 117 | 118 | With the extension now published on the Marketplace, commit the 119 | change, create a tag, push, cut a GitHub (pre-)release, and create a 120 | pull request against `main`: 121 | 122 | ```bash 123 | ( 124 | set -eux 125 | git checkout -b publish 126 | tag="$(jq -r '"v" + .version' extension/share/dist/package.json)" 127 | echo "New tag: ${tag}" 128 | git add -u 129 | git commit --edit -m "Release ${tag}" 130 | git tag "${tag}" 131 | git push --tags 132 | gh release create --generate-notes "${tag}" 133 | gh pr create --fill --web 134 | ) 135 | ``` 136 | 137 | ## Maintenance 138 | 139 | ### yarn install 140 | 141 | To install the current project dependencies as specified in 142 | `package.json` and `yarn.lock`, run `yarn install`. 143 | 144 | ### yarn clean-install 145 | 146 | If the Yarn version has changed and you run `yarn install`, Yarn 147 | will try to upgrade itself. That causes changes to several files, 148 | such as the `LICENSE` files I have placed into several 149 | subdirectories. 150 | 151 | Anytime that happens, run the `yarn clean-install` script, a wrapper 152 | around `yarn install` which cleans up afterwards. 153 | 154 | Note that the `yarn clean-install` script may fail and tell you to 155 | run `yarn install` instead. I haven’t figured out why it does that. 156 | If that happens, run `yarn install` followed by `yarn clean-install`. 157 | 158 | ### yarn outdated 159 | 160 | To see a list of outdated packages, run: `yarn outdated` 161 | 162 | ### yarn upgrade-lockfile 163 | 164 | This runs `yarn up -R '**' && yarn clean-install` behind the scenes 165 | in order to upgrade all resolutions in the lockfile as far as 166 | possible, but leaves your `package.json` as is. 167 | 168 | ### yarn upgrade-packages 169 | 170 | The built-in `yarn up` command can be a bit cumbersome to use if you 171 | want to upgrade all dependencies in one go. 172 | 173 | Running the `yarn upgrade-packages` script will upgrade all relevant 174 | dependencies. That includes the `@types`, `@typescript-eslint`, and 175 | `@yarnpkg` scopes but excludes Yarn itself (see the 176 | `yarn upgrade-yarn-itself` section). 177 | 178 | Also excluded is the `@types/vscode` package. For details, see 179 | section _Upgrading the VS Code API version_. 180 | 181 | ### yarn upgrade-yarn-itself 182 | 183 | To upgrade Yarn PnP to the latest available version, run the 184 | `yarn upgrade-yarn-itself` script. 185 | 186 | Note that the script will only print manual instructions. That’s 187 | because Yarn makes changes to `package.json`, and that doesn’t play 188 | well with Yarn PnP in scripts. 189 | 190 | ### yarn upgrade-all 191 | 192 | To also upgrade Yarn itself, run `yarn upgrade-all`. 193 | 194 | ### Upgrading the VS Code API version 195 | 196 | Upgrading the version of the `@types/vscode` package should always 197 | be a manual step and a conscious decision. It effectively bumps the 198 | minimum supported VS Code version that this extension supports. 199 | 200 | To bump the minimum supported VS Code version, follow these steps: 201 | 202 | 1. In `extension/package.json`, manually update the minimum version 203 | to a new version tuple (e.g. `=1.99`). 204 | Make sure to preserve the `=` prefix as you change the value. 205 | 206 | 2. In the root `package.json` file, modify the `upgrade-package` 207 | script to update the same tuple (e.g `@types/vscode@=1.99`). 208 | Preserve the `@types/vscode@=` prefix as you change the value. 209 | 210 | 3. In `extension/share/dist/package.json` under the `engines` 211 | section, manually update the value of the `vscode` property to 212 | the chosen version. 213 | Since `vsce` expects a triple for that property, append a `.0`. 214 | Preserve the `^` prefix as you change the value. 215 | 216 | 4. Run `yarn clean-install`. 217 | 218 | ## Patching dependencies 219 | 220 | Sometimes you may want to tweak a dependency. This section explains how to do that using `yarn patch`. 221 | 222 | ### Start editing 223 | 224 | To start editing a dependency, run `yarn patch `. 225 | 226 | For example, to start editing the `vsce` executable, run: 227 | 228 | ```shell 229 | yarn patch @vscode/vsce@npm:2.21.1 230 | ``` 231 | 232 | Since this project is already patching this dependency, you may want to apply the existing patch to the temporary working directory: 233 | 234 | ```shell 235 | patch < path/to/this/project/.yarn/patches/@vscode-vsce-npm-2.21.1.patch 236 | ``` 237 | 238 | ### Committing a patch for the first time 239 | 240 | To commit a patch for the first time, run `yarn patch-commit -s `. 241 | 242 | ### Modifying an existing patch 243 | 244 | To commit a modified patch, run `yarn repatch -- `. 245 | 246 | For example, if the temporary working directory is `/tmp/xfs-36e26fe6/user`, run: 247 | 248 | ```shell 249 | yarn repatch -- /tmp/xfs-36e26fe6/user 250 | ``` 251 | 252 | Note: `yarn repatch` is a custom script. It serves to work around two issues in `yarn patch-commit`: 253 | 254 | - Using bare `yarn patch-commit` would create a nested patch while amending the patch is what I actually want. 255 | 256 | - It may also use an incorrect key in the resolution entry it writes to `package.json`. 257 | The key should match the dependency’s semver expression, not the resolved version. 258 | Using the latter as a key causes the resolution to never apply. 259 | Example for a correct key: `"@vscode/vsce@^2.21.1"` 260 | 261 | ## Handling vulnerable dependencies 262 | 263 | ### The thing about vulnerabilities in transitive dependencies 264 | 265 | People sometimes discover vulnerabilities in packages on which 266 | vscode-packaging depends. 267 | 268 | If that happens and a patch comes out, I need to upgrade the 269 | affected package to a newer version, which includes the patch. 270 | 271 | But a vulnerability might also affect a package on which 272 | vscode-packaging depends only indirectly, e.g. through a 273 | transitive requirement. A patch may exist for such a package, but 274 | somewhere in the chain of dependencies (from the vulnerable package 275 | all the way down to vscode-packaging), the patch may be 276 | outside the specified semver range so I **can’t upgrade** the 277 | package via the usual `yarn up` or `yarn up -R` command. 278 | 279 | ### Dealing with the risk 280 | 281 | If such cases arise, I’m going to try force-upgrading affected 282 | packages, and document those upgrades in the section 283 | _List of force-upgraded transitive dependencies_ below. 284 | Even if the upgrade happens to fail (or if it breaks the app and I 285 | have to roll back the upgrade, leaving the vulnerability unpatched), 286 | I’m also going to document that failure here. 287 | 288 | ## List of force-upgraded transitive dependencies 289 | 290 | The goal of this list is: 291 | 292 | - to document the drift between version requirements (in the tree 293 | of `package.json` files) and the resolutions in `yarn.lock`; and 294 | 295 | - to inform about unpatched vulnerabilities. 296 | 297 | No entries yet. 298 | 299 | 303 | 304 | 317 | 318 | ## See also 319 | 320 | - [TextMate language grammars](https://macromates.com/manual/en/language_grammars) 321 | - Default themes 322 | [dark_vs](https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/dark_vs.json) 323 | and 324 | [dark_plus](https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/dark_plus.json) 325 | as references on how VS Code renders grammar scopes. 326 | 327 | ## License 328 | 329 | This source code repository contains code and assets sourced from 330 | different parties. Therefore, multiple sets of license terms apply 331 | to different parts of this source code repository. 332 | 333 | The following table shows which terms apply to which parts of this 334 | source code repository: 335 | 336 | | Directory tree | Description | License | Terms | 337 | |---|---|---|---| 338 | | `.` | This directory | Apache-2.0 | [License](./LICENSE)
with License header below | 339 | | `./.yarn/releases` | The `yarn` package manager | BSD-2-Clause | [License](./.yarn/releases/LICENSE) | 340 | | `./.yarn/sdks` | SDK files for `yarn` | BSD-2-Clause | [License](./.yarn/sdks/LICENSE) | 341 | | `./extension` | Front-end source code for this VS Code extension | Apache-2.0 | [License](./extension/LICENSE.txt)
with [License header](./extension/README.md#license) | 342 | 343 | In each of the directories the table mentions, you will find one 344 | license file, named `LICENSE` or `LICENSE.txt`. 345 | Each license file applies to the directory that contains it, 346 | including all subdirectories, but excluding any subdirectory tree 347 | whose root has a license file on its own. 348 | 349 | ## License header 350 | 351 | Copyright (c) 2022–2024 Claudia Pellegrino 352 | 353 | Licensed under the Apache License, Version 2.0 (the "License"); 354 | you may not use this file except in compliance with the License. 355 | For a copy of the License, see [LICENSE](LICENSE). 356 | -------------------------------------------------------------------------------- /extension/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | env: 2 | node: true 3 | extends: 4 | - eslint:recommended 5 | - plugin:@typescript-eslint/recommended-type-checked 6 | - plugin:@typescript-eslint/stylistic-type-checked 7 | ignorePatterns: 8 | - build/ 9 | - work/ 10 | parser: "@typescript-eslint/parser" 11 | parserOptions: 12 | ecmaFeatures: 13 | impliedStrict: true 14 | ecmaVersion: 2022 15 | project: 16 | - tsconfig.json 17 | plugins: 18 | - "@typescript-eslint" 19 | root: true 20 | rules: 21 | array-bracket-spacing: 1 22 | arrow-spacing: 1 23 | block-spacing: 1 24 | brace-style: 1 25 | camelcase: 1 26 | class-methods-use-this: 1 27 | comma-dangle: [1, always-multiline] 28 | comma-spacing: 1 29 | comma-style: 1 30 | complexity: 1 31 | computed-property-spacing: 1 32 | consistent-return: 1 33 | consistent-this: 1 34 | default-case-last: 1 35 | default-case: 2 36 | dot-location: [1, property] 37 | dot-notation: [1, { allowKeywords: false }] 38 | eqeqeq: 1 39 | func-call-spacing: 1 40 | generator-star-spacing: [1, before] 41 | guard-for-in: 1 42 | indent: [1, 2] 43 | key-spacing: 1 44 | linebreak-style: 2 45 | lines-between-class-members: [1, always, { exceptAfterSingleLine: true }] 46 | logical-assignment-operators: [1, always, { enforceForIfStatements: true }] 47 | max-depth: 1 48 | max-len: 49 | - 1 50 | - code: 80 51 | ignorePattern: ^\s*/[/*] eslint-disable 52 | ignoreUrls: true 53 | max-lines-per-function: 1 54 | max-lines: 1 55 | newline-per-chained-call: [1, { ignoreChainWithDepth: 2 }] 56 | no-alert: 2 57 | no-console: 2 58 | no-implied-eval: 1 59 | no-invalid-this: 2 60 | no-lone-blocks: 1 61 | no-lonely-if: 1 62 | no-loop-func: 1 63 | no-mixed-operators: 1 64 | no-multi-assign: 1 65 | no-multi-spaces: 1 66 | no-multiple-empty-lines: [1, { max: 1 }] 67 | no-negated-condition: 1 68 | no-octal-escape: 2 69 | no-return-assign: 1 70 | no-self-compare: 1 71 | no-shadow: 1 72 | no-tabs: 2 73 | no-template-curly-in-string: 1 74 | no-throw-literal: 2 75 | no-trailing-spaces: 1 76 | no-undefined: 1 77 | no-unexpected-multiline: 1 78 | no-unused-expressions: 1 79 | 80 | # For compatibility with typescript-eslint 81 | no-unused-vars: 0 82 | 83 | no-useless-concat: 1 84 | no-var: 1 85 | no-whitespace-before-property: 1 86 | object-shorthand: 1 87 | operator-assignment: 1 88 | prefer-const: 1 89 | prefer-destructuring: 1 90 | prefer-exponentiation-operator: 1 91 | prefer-named-capture-group: 1 92 | prefer-object-has-own: 1 93 | prefer-object-spread: 1 94 | prefer-regex-literals: 1 95 | prefer-rest-params: 1 96 | prefer-spread: 1 97 | prefer-template: 1 98 | quote-props: [1, as-needed] 99 | quotes: 1 100 | radix: 1 101 | require-await: 1 102 | require-yield: 1 103 | rest-spread-spacing: 1 104 | semi-spacing: 1 105 | semi-style: 1 106 | sort-imports: [1, { ignoreCase: true, ignoreDeclarationSort: true }] 107 | sort-vars: 1 108 | space-before-blocks: 1 109 | space-before-function-paren: [1, { named: never }] 110 | space-in-parens: 1 111 | space-infix-ops: 1 112 | space-unary-ops: 1 113 | spaced-comment: 1 114 | unicode-bom: 2 115 | yoda: 1 116 | 117 | "@typescript-eslint/array-type": 1 118 | 119 | # In VS Code, this allows developers to manually specify 120 | # inferrable types so the distracting inline hints go away 121 | "@typescript-eslint/no-inferrable-types": 0 122 | 123 | # https://github.com/typescript-eslint/typescript-eslint/issues/4912 124 | "@typescript-eslint/no-unsafe-argument": 0 125 | "@typescript-eslint/no-unsafe-assignment": 0 126 | "@typescript-eslint/no-unsafe-member-access": 0 127 | 128 | "@typescript-eslint/no-unused-vars": [1, { argsIgnorePattern: ^_, varsIgnorePattern: ^_ }] 129 | "@typescript-eslint/unbound-method": 0 130 | -------------------------------------------------------------------------------- /extension/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /dist/ 3 | /types/ 4 | /work/ 5 | -------------------------------------------------------------------------------- /extension/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /extension/README.md: -------------------------------------------------------------------------------- 1 | # Packaging 2 | 3 | This extension helps you work with package definition files for 4 | package repositories. 5 | 6 | It currently supports only a single type of package repository: the 7 | [Arch User Repository](https://aur.archlinux.org/) (AUR). 8 | 9 | ## Screenshots 10 | 11 | ### PKGBUILD (AUR) 12 | 13 | | `PKGBUILD` file without this extension | `PKGBUILD` file with this extension | 14 | |:--------------------------------------:|:-----------------------------------:| 15 | | Screenshot of a PKGBUILD file opened in VS Code without the Packaging extension installed. The screenshot shows dozens of ShellCheck diagnostics, most of which are useless for PKGBUILDs. The two relevant findings are difficult to spot because they have become lost in the noise. | Screenshot of a PKGBUILD file opened in VS Code with the Packaging extension installed. The screenshot now only shows the two ShellCheck findings which are actual mistakes in the PKGBUILD. | 16 | | [ShellCheck](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck) findings are mostly irrelevant. | Only see ShellCheck diagnostics that matter. | 17 | 18 | ### customizepkg 19 | 20 | | [`customizepkg`](https://github.com/ava1ar/customizepkg) patch file with syntax highlighting | 21 | |:---------------------------------------------------:| 22 | | Screenshot of a customizepkg-style patch file opened in VS Code with the Packaging extension installed, showcasing support for syntax highlighting. | 23 | 24 | ## Features 25 | 26 | ### PKGBUILD (AUR) features 27 | 28 | The Packaging extension supports user-contributed 29 | [PKGBUILD](https://wiki.archlinux.org/title/PKGBUILD) files in the 30 | AUR. 31 | 32 | For `PKGBUILD` files opened in VS Code, this extension enables 33 | linting through the 34 | [ShellCheck](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck) 35 | extension. 36 | 37 | By default, however, ShellCheck emits a number of unhelpful warnings 38 | that are false alarms in the context of `PKGBUILD` files. To remove 39 | those false alarms, this extension configures the ShellCheck 40 | extension in the following ways: 41 | 42 | - Sets Bash as the shell. 43 | 44 | - Disables rule [SC2034](https://www.shellcheck.net/wiki/SC2034) 45 | _(“foo appears unused. Verify it or export it.”)_ 46 | 47 | - Disables rule [SC2154](https://www.shellcheck.net/wiki/SC2154) 48 | _(“var is referenced but not assigned.”)_ 49 | 50 | - Disables rule [SC2164](https://www.shellcheck.net/wiki/SC2164) 51 | _(“Use `cd ... || exit` in case `cd` fails.”)_ 52 | 53 | - Will not affect regular shell scripts, only `PKGBUILD`s 54 | 55 | ### Pacman \*.install files 56 | 57 | The Packaging extension adds syntax highlighting to Pacman `*.install` 58 | files. 59 | 60 | It also sets Bash as the shell, removing an unnecessary Shellcheck 61 | warning. 62 | 63 | ### customizepkg syntax highlighting 64 | 65 | The Packaging extension provides syntax highlighting for 66 | [`customizepkg-git`](https://aur.archlinux.org/packages/customizepkg-git)AUR 67 | patch files. 68 | 69 | For details and examples about `customizepkg`, see 70 | [customizepkg](https://github.com/ava1ar/customizepkg) on GitHub. 71 | 72 | ## Prerequisites 73 | 74 | This extension depends on the 75 | [ShellCheck extension](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck), 76 | maintained by Felipe Santos. 77 | 78 | Usually, VS Code will take care of this dependency for you. 79 | When in doubt, you can reinstall the ShellCheck extension to get the 80 | latest version. You should have to do that only once though, if 81 | ever. 82 | 83 | ## FAQ 84 | 85 | - Q. Why does this extension set Bash as the shell? 86 | A. `makepkg`, the program that sources `PKGBUILD`s, runs in Bash. 87 | The same goes for Pacman `*.install` files. 88 | 89 | - Q. Why does this extension disable rule SC2164 for `PKGBUILD`s? 90 | A. `makepkg` first configures `shopt -o -s errexit`, which is 91 | roughly equivalent to `set -e` , before it calls into 92 | `PKGBUILD`’s functions. ShellCheck doesn’t know this, and 93 | still reports SC2164 violations, but those are unhelpful false 94 | alarms in that context. 95 | 96 | - Q. Why does this extension disable rule SC2034 for `PKGBUILD`s? 97 | A. There are 98 | [more than a dozen PKGBUILD variables](https://wiki.archlinux.org/title/PKGBUILD). 99 | ShellCheck emits `SC2034` violations for every single one of 100 | them, because it can’t tell that `makepkg` will consume those 101 | variables after it sources the `PKGBUILD`. So those are 102 | unhelpful false alarms. 103 | Disabling rule SC2034 incurs some collateral damage, but due to 104 | [limitations in ShellCheck itself](https://github.com/koalaman/shellcheck/issues/356), 105 | this is probably the best we can do for now. 106 | 107 | - Q. Why does this extension disable rule SC2154 for `PKGBUILD`s? 108 | A. Similarly to SC2034, ShellCheck emits `SC2154` violations for 109 | variables like `srcdir` and `pkgdir`, because it can’t tell 110 | that `makepkg` always pre-initializes those variables before it 111 | calls into `PKGBUILD` functions. Hence, these are false alarms, 112 | too. 113 | Just like SC2034, disabling rule SC2154 will also suppress 114 | some legitimate ShellCheck warnings but we can’t do anything 115 | about it unless someone introduces 116 | [the missing feature](https://github.com/koalaman/shellcheck/issues/356) 117 | to ShellCheck proper. 118 | 119 | ## Acknowledgements 120 | 121 | A shout-out to these amazing people: 122 | 123 | - [Felipe Santos](https://github.com/felipecrs), maintainer of the 124 | [VS Code extension for ShellCheck](https://github.com/vscode-shellcheck/vscode-shellcheck) 125 | 126 | - [Mark Skelton](https://github.com/mskelton), author of 127 | [yarn-plugin-outdated](https://github.com/mskelton/yarn-plugin-outdated) 128 | 129 | - [Vidar Holen](https://github.com/koalaman), who wrote 130 | [ShellCheck](https://www.shellcheck.net/) 131 | 132 | ## License 133 | 134 | Copyright (c) 2022–2024 Claudia Pellegrino 135 | 136 | Licensed under the Apache License, Version 2.0 (the "License"); 137 | you may not use this file except in compliance with the License. 138 | For a copy of the License, see [LICENSE.txt](LICENSE.txt). 139 | -------------------------------------------------------------------------------- /extension/contrib/build.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import esbuild from 'esbuild' 4 | import copyStaticFiles from 'esbuild-copy-static-files' 5 | 6 | await esbuild.build({ 7 | entryPoints: ['work/tsc-out/extension.js'], 8 | bundle: true, 9 | external: ['vscode'], 10 | platform: 'node', 11 | outdir: 'build/', 12 | plugins: [ 13 | copyStaticFiles({ 14 | src: 'share/dist/', 15 | dest: 'build/', 16 | }), 17 | copyStaticFiles({ 18 | src: 'share/language/', 19 | dest: 'build/language/', 20 | }), 21 | copyStaticFiles({ 22 | src: 'LICENSE.txt', 23 | dest: 'build/LICENSE.txt', 24 | }), 25 | copyStaticFiles({ 26 | src: 'README.md', 27 | dest: 'build/README.md', 28 | }), 29 | ], 30 | }) 31 | -------------------------------------------------------------------------------- /extension/examples/PKGBUILD: -------------------------------------------------------------------------------- 1 | # This is an example PKGBUILD file. Use this as a start to creating your own, 2 | # and remove these comments. For more information, see 'man PKGBUILD'. 3 | # NOTE: Please fill out the license field for your package! If it is unknown, 4 | # then please put 'unknown'. 5 | 6 | # Maintainer: Your Name 7 | pkgname=NAME 8 | pkgver=VERSION 9 | pkgrel=1 10 | epoch= 11 | pkgdesc="" 12 | arch=() 13 | url="" 14 | license=('GPL') 15 | groups=() 16 | depends=() 17 | makedepends=() 18 | checkdepends=() 19 | optdepends=() 20 | provides=() 21 | conflicts=() 22 | replaces=() 23 | backup=() 24 | options=() 25 | install= 26 | changelog= 27 | source=("$pkgname-$pkgver.tar.gz" 28 | "$pkgname-$pkgver.patch") 29 | noextract=() 30 | md5sums=() 31 | validpgpkeys=() 32 | 33 | prepare() { 34 | cd "$pkgname-$pkgver" 35 | patch -p1 -i "$srcdir/$pkgname-$pkgver.patch" 36 | } 37 | 38 | build() { 39 | cd "$pkgname-$pkgver" 40 | ./configure --prefix=/usr 41 | make 42 | } 43 | 44 | check() { 45 | cd "$pkgname-$pkgver" 46 | make -k check 47 | } 48 | 49 | package() { 50 | cd "$pkgname-$pkgver" 51 | make DESTDIR="$pkgdir/" install 52 | } 53 | -------------------------------------------------------------------------------- /extension/examples/debian/foo.install: -------------------------------------------------------------------------------- 1 | foo 2 | bar 3 | baz 4 | -------------------------------------------------------------------------------- /extension/examples/dymoprint: -------------------------------------------------------------------------------- 1 | # https://aur.archlinux.org/packages/dymoprint#comment-922629 2 | 3 | replace#pkgrel#1#2 4 | add#makedepends#unzip 5 | add#makedepends#zip 6 | addline#global#4e99d')#prepare() { 7 | addline#prepare#prepare# cd "$(mktemp -d)" 8 | addline#prepare#mktemp# unzip "${srcdir}/${pkgname}-${pkgver}-py2.py3-none-any.whl" 9 | 10 | # https://pillow.readthedocs.io/en/stable/releasenotes/9.2.0.html#font-size-and-offset-methods 11 | addline#prepare#unzip# sed -i -e 's/max(.* \\(for line in labeltext\\)/max(r - l for l, _, r, _ in (font.getbbox(line) \\1)/' dymoprint/command_line.py 12 | 13 | # https://pillow.readthedocs.io/en/stable/releasenotes/10.0.0.html#constants 14 | addline#prepare#sed# sed -i -e 's/ANTIALIAS/LANCZOS/g' dymoprint/command_line.py 15 | 16 | addline#prepare#ANTIALIAS# zip -ur "${srcdir}/${pkgname}-${pkgver}-py2.py3-none-any.patched.whl" * 17 | addline#prepare# zip#} 18 | replace#package#*.whl#"${pkgname}-${pkgver}-py2.py3-none-any.patched.whl" 19 | -------------------------------------------------------------------------------- /extension/examples/foo.install: -------------------------------------------------------------------------------- 1 | # The function is run right before files are extracted. 2 | # One argument is passed: new package version. 3 | pre_install() { 4 | : 5 | } 6 | 7 | # The function is run right after files are extracted. 8 | # One argument is passed: new package version. 9 | post_install() { 10 | : 11 | } 12 | 13 | # The function is run right before files are extracted. 14 | # Two arguments are passed in the following order: 15 | # new package version, old package version. 16 | pre_upgrade() { 17 | : 18 | } 19 | 20 | # The function is run right after files are extracted. 21 | # Two arguments are passed in the following order: 22 | # new package version, old package version. 23 | post_upgrade() { 24 | : 25 | } 26 | 27 | # The function is run right before files are removed. 28 | # One argument is passed: old package version. 29 | pre_remove() { 30 | : 31 | } 32 | 33 | # The function is run right after files are removed. 34 | # One argument is passed: old package version. 35 | post_remove() { 36 | : 37 | } 38 | -------------------------------------------------------------------------------- /extension/images/screenshot-customizepkg-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claui/vscode-packaging/1873c5ba4de455f9003b1d364c3d2a7df38369a7/extension/images/screenshot-customizepkg-patch.png -------------------------------------------------------------------------------- /extension/images/screenshot-pkgbuild-with-extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claui/vscode-packaging/1873c5ba4de455f9003b1d364c3d2a7df38369a7/extension/images/screenshot-pkgbuild-with-extension.png -------------------------------------------------------------------------------- /extension/images/screenshot-pkgbuild-without-extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claui/vscode-packaging/1873c5ba4de455f9003b1d364c3d2a7df38369a7/extension/images/screenshot-pkgbuild-without-extension.png -------------------------------------------------------------------------------- /extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "extension", 3 | "license": "SEE LICENSE IN README.md", 4 | "comments": { 5 | "devDependencies": { 6 | "@types/node": "Keep this pinned to the Node.js major version that ships with VS Code.", 7 | "@types/vscode": "For details, see section *Upgrading the VS Code API version* in `README.md`." 8 | } 9 | }, 10 | "dependencies": { 11 | "packaging": "workspace:^" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "<=20.x", 15 | "@types/vscode": "=1.92", 16 | "@typescript-eslint/eslint-plugin": "<=7.x", 17 | "@typescript-eslint/parser": "<=7.x", 18 | "@vscode/vsce": "^2.21.1", 19 | "del-cli": "^5.1.0", 20 | "esbuild": "^0.23.1", 21 | "esbuild-copy-static-files": "^0.1.0", 22 | "eslint": "<=8.x", 23 | "ovsx": "^0.9.4", 24 | "semver": "^7.6.3", 25 | "source-map-support": "^0.5.21", 26 | "ts-node": "^10.9.2", 27 | "typescript": "<=5.5.x" 28 | }, 29 | "scripts": { 30 | "ci-package": "mkdir -p dist && yarn run -B vsce package --no-dependencies --yarn --cwd build --githubBranch main/extension --out dist", 31 | "clean": "yarn run -B del build dist types work", 32 | "compile": "yarn run -B tsc && contrib/build.mjs", 33 | "lint": "yarn run -B eslint --max-warnings 0 src", 34 | "login": "yarn run -B vsce login claui", 35 | "package": "yarn clean && yarn compile && yarn ci-package", 36 | "publish-vsce": "yarn run -B vsce publish --no-dependencies --yarn --cwd build --githubBranch main/extension", 37 | "repatch": "git add -- package.json && yarn patch-commit -s \"$1\" && git checkout -- package.json && yarn clean-install", 38 | "vscode:prepublish": "yarn clean && yarn compile" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /extension/share/context.sh: -------------------------------------------------------------------------------- 1 | # 2 | # This script is meant to be sourced by ShellCheck. Its purpose is 3 | # to provide context for PKGBUILD files, preventing unnecessary 4 | # warnings. 5 | # 6 | 7 | # Allow ShellCheck to interpret this file correctly during development: 8 | # shellcheck shell=bash 9 | 10 | # ShellCheck does not recognize `shopt -o -s errexit` so we use `set -e`. 11 | # 12 | # See also: 13 | # https://gitlab.archlinux.org/pacman/pacman/-/blob/e017a5975cfe3e53670848bd45c982524d6745af/scripts/makepkg.sh.in#L396 14 | set -e 15 | 16 | # See also: 17 | # https://gitlab.archlinux.org/pacman/pacman/-/blob/e017a5975cfe3e53670848bd45c982524d6745af/scripts/libmakepkg/util/util.sh.in#L106 18 | shopt -u extglob 19 | 20 | # Variable names pseudo-exported from PKGBUILD files. 21 | # 22 | # I have sourced the following list from namcap; see also: 23 | # https://github.com/keenerd/namcap/blob/master/Namcap/rules/extravars.py 24 | export arch 25 | export b2sums 26 | export backup 27 | export changelog 28 | export checkdepends 29 | export conflicts 30 | export depends 31 | export epoch 32 | export groups 33 | export install 34 | export license 35 | export makedepends 36 | export md5sums 37 | export noextract 38 | export optdepends 39 | export options 40 | export pkgbase 41 | export pkgdesc 42 | export pkgname 43 | export pkgrel 44 | export pkgver 45 | export provides 46 | export replaces 47 | export sha1sums 48 | export sha224sums 49 | export sha256sums 50 | export sha384sums 51 | export sha512sums 52 | export source 53 | export url 54 | export validpgpkeys 55 | 56 | # Variables exported from makepkg. See also: 57 | # https://wiki.archlinux.org/title/Creating_packages#Defining_PKGBUILD_variables 58 | export srcdir 59 | export pkgdir 60 | 61 | # Environment variables that makepkg accepts. See also: 62 | # https://gitlab.archlinux.org/pacman/pacman/-/blob/e017a5975cfe3e53670848bd45c982524d6745af/doc/makepkg.8.asciidoc#user-content-environment-variables 63 | export BUILDDIR 64 | export BUILDTOOL 65 | export BUILDTOOLVER 66 | export CARCH 67 | export GITFLAGS 68 | export GNUPGHOME 69 | export GPGKEY 70 | export LOGDEST 71 | export MAKEPKG_CONF 72 | export PACKAGER 73 | export PACMAN 74 | export PKGDEST 75 | export PKGEXT 76 | export SOURCE_DATE_EPOCH 77 | export SRCDEST 78 | export SRCPKGDEST 79 | -------------------------------------------------------------------------------- /extension/share/dist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "packaging", 3 | "version": "0.2.5", 4 | "publisher": "claui", 5 | "engines": { 6 | "vscode": "^1.92.0" 7 | }, 8 | "license": "SEE LICENSE IN README.md", 9 | "displayName": "Packaging", 10 | "description": "Support for user-contributed PKGBUILDs in the Arch User Repository (AUR)", 11 | "categories": [], 12 | "keywords": [], 13 | "main": "extension.js", 14 | "contributes": { 15 | "commands": [ 16 | { 17 | "command": "packaging.action.showLog", 18 | "title": "Packaging: Show extension log" 19 | } 20 | ], 21 | "configurationDefaults": { 22 | "[aur-pkgbuild]": { 23 | "shellcheck.customArgs": [ 24 | "--external-sources", 25 | "--shell", 26 | "bash" 27 | ], 28 | "shellcheck.exclude": [ 29 | "2034", 30 | "2154", 31 | "2164" 32 | ] 33 | }, 34 | "[pacman-install-script]": { 35 | "shellcheck.customArgs": [ 36 | "--external-sources", 37 | "--shell", 38 | "bash" 39 | ] 40 | }, 41 | "files.associations": { 42 | "**/debian/*.install": "plain" 43 | } 44 | }, 45 | "grammars": [ 46 | { 47 | "language": "aur-pkgbuild", 48 | "scopeName": "source.shell.pkgbuild.aur", 49 | "path": "language/aur-pkgbuild.tmLanguage.json" 50 | }, 51 | { 52 | "language": "pacman-install-script", 53 | "scopeName": "source.shell.install-script.pacman", 54 | "path": "language/pacman-install-script.tmLanguage.json" 55 | }, 56 | { 57 | "language": "customizepkg-patch", 58 | "scopeName": "source.customizepkg-patch", 59 | "path": "language/customizepkg-patch.tmLanguage.json" 60 | } 61 | ], 62 | "languages": [ 63 | { 64 | "id": "aur-pkgbuild", 65 | "aliases": [ 66 | "PKGBUILD (AUR)" 67 | ], 68 | "filenames": [ 69 | "PKGBUILD" 70 | ], 71 | "configuration": "language/aur-pkgbuild.language-configuration.json" 72 | }, 73 | { 74 | "id": "pacman-install-script", 75 | "aliases": [ 76 | "Pacman *.install script" 77 | ], 78 | "filenamePatterns": [ 79 | "**/*.install" 80 | ], 81 | "configuration": "language/pacman-install-script.language-configuration.json" 82 | }, 83 | { 84 | "id": "customizepkg-patch", 85 | "aliases": [ 86 | "PKGBUILD patch file" 87 | ], 88 | "filenamePatterns": [ 89 | "**/.customizepkg/*", 90 | "**/customizepkg.d/*" 91 | ], 92 | "configuration": "language/customizepkg-patch.language-configuration.json" 93 | } 94 | ] 95 | }, 96 | "extensionDependencies": [ 97 | "timonwong.shellcheck" 98 | ], 99 | "extensionKind": [ 100 | "workspace" 101 | ], 102 | "activationEvents": [], 103 | "repository": "github:claui/vscode-packaging" 104 | } 105 | -------------------------------------------------------------------------------- /extension/share/language/aur-pkgbuild.language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "#" 4 | }, 5 | "brackets": [ 6 | [ 7 | "{", 8 | "}" 9 | ], 10 | [ 11 | "[", 12 | "]" 13 | ], 14 | [ 15 | "(", 16 | ")" 17 | ] 18 | ], 19 | "autoClosingPairs": [ 20 | [ 21 | "{", 22 | "}" 23 | ], 24 | [ 25 | "[", 26 | "]" 27 | ], 28 | [ 29 | "(", 30 | ")" 31 | ], 32 | { 33 | "open": "\"", 34 | "close": "\"", 35 | "notIn": [ 36 | "string" 37 | ] 38 | }, 39 | { 40 | "open": "'", 41 | "close": "'", 42 | "notIn": [ 43 | "string" 44 | ] 45 | }, 46 | { 47 | "open": "`", 48 | "close": "`", 49 | "notIn": [ 50 | "string" 51 | ] 52 | } 53 | ], 54 | "surroundingPairs": [ 55 | [ 56 | "{", 57 | "}" 58 | ], 59 | [ 60 | "[", 61 | "]" 62 | ], 63 | [ 64 | "(", 65 | ")" 66 | ], 67 | [ 68 | "\"", 69 | "\"" 70 | ], 71 | [ 72 | "'", 73 | "'" 74 | ], 75 | [ 76 | "`", 77 | "`" 78 | ] 79 | ], 80 | "folding": { 81 | "markers": { 82 | "start": "^\\s*#\\s*#?region\\b.*", 83 | "end": "^\\s*#\\s*#?endregion\\b.*" 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /extension/share/language/aur-pkgbuild.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aur-pkgbuild", 3 | "scopeName": "source.shell.pkgbuild.aur", 4 | "uuid": "b758f368-67dc-4719-b095-756c7051c313", 5 | "comment": "PKGBUILD (AUR)", 6 | "patterns": [ 7 | { 8 | "include": "source.shell" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /extension/share/language/customizepkg-patch.language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "#" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /extension/share/language/customizepkg-patch.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PKGBUILD patch file", 3 | "scopeName": "source.customizepkg-patch", 4 | "uuid": "30610fd9-2339-45ae-ade4-d29d42df7e67", 5 | "patterns": [ 6 | { 7 | "comment": "Line comments take precedence before everything else", 8 | "include": "#comment" 9 | }, 10 | { 11 | "comment": "The `add` directive", 12 | "include": "#add" 13 | }, 14 | { 15 | "comment": "The `addline` directive", 16 | "include": "#addline" 17 | }, 18 | { 19 | "comment": "The `patch` directive", 20 | "include": "#patch" 21 | }, 22 | { 23 | "comment": "The `remove` and `removeline` directives", 24 | "include": "#remove" 25 | }, 26 | { 27 | "comment": "The `replace` directive", 28 | "include": "#replace" 29 | }, 30 | { 31 | "comment": "Unknown directive", 32 | "include": "#unknown" 33 | } 34 | ], 35 | "repository": { 36 | "add": { 37 | "match": "^(add)(#)([^#]*)(#)(.*)", 38 | "captures": { 39 | "1": { 40 | "name": "keyword.other.verb.$1.customizepkg" 41 | }, 42 | "2": { 43 | "name": "punctuation.separator.field" 44 | }, 45 | "3": { 46 | "name": "meta.section.$1.context.customizepkg", 47 | "patterns": [ 48 | { 49 | "include": "#pkgbuild-context-directive" 50 | } 51 | ] 52 | }, 53 | "4": { 54 | "name": "punctuation.separator.field" 55 | }, 56 | "5": { 57 | "name": "meta.section.$3.$1 markup.inserted.$1" 58 | } 59 | } 60 | }, 61 | "addline": { 62 | "match": "^(addline)(#)([^#]*)(#)(.*)", 63 | "captures": { 64 | "1": { 65 | "name": "keyword.other.verb.$1.customizepkg" 66 | }, 67 | "2": { 68 | "name": "punctuation.separator.field" 69 | }, 70 | "3": { 71 | "name": "meta.section.$1.context.customizepkg", 72 | "patterns": [ 73 | { 74 | "include": "#pkgbuild-context-global" 75 | }, 76 | { 77 | "include": "#pkgbuild-context-directive" 78 | } 79 | ] 80 | }, 81 | "4": { 82 | "name": "punctuation.separator.field" 83 | }, 84 | "5": { 85 | "name": "meta.section.$3.$1 markup.inserted.$1" 86 | } 87 | } 88 | }, 89 | "comment": { 90 | "match": "^((#).*)$", 91 | "captures": { 92 | "1": { 93 | "name": "comment.line.customizepkg" 94 | }, 95 | "2": { 96 | "name": "punctuation.definition.comment.customizepkg" 97 | } 98 | } 99 | }, 100 | "patch": { 101 | "match": "^(patch)(#)(.*)", 102 | "captures": { 103 | "1": { 104 | "name": "keyword.other.verb.$1.customizepkg" 105 | }, 106 | "2": { 107 | "name": "punctuation.separator.field" 108 | }, 109 | "3": { 110 | "name": "meta.section.$1.context.customizepkg", 111 | "patterns": [ 112 | { 113 | "match": "([^#]*)(#)(.*)", 114 | "captures": { 115 | "1": { 116 | "patterns": [ 117 | { 118 | "include": "#pkgbuild-context-pkgbuild" 119 | }, 120 | { 121 | "match": ".*", 122 | "name": "invalid.illegal.context" 123 | } 124 | ] 125 | }, 126 | "2": { 127 | "name": "punctuation.separator.field" 128 | }, 129 | "3": { 130 | "name": "string.unquoted.patch.filename" 131 | } 132 | } 133 | }, 134 | { 135 | "match": ".*", 136 | "name": "string.unquoted.patch.filename" 137 | } 138 | ] 139 | }, 140 | "4": { 141 | "name": "punctuation.separator.field" 142 | }, 143 | "5": { 144 | "name": "meta.section.$3.$1 markup.inserted.$1" 145 | } 146 | } 147 | }, 148 | "pkgbuild-context-directive": { 149 | "patterns": [ 150 | { 151 | "match": "\\b[a-zA-Z_0-9-]+\\b", 152 | "name": "variable.other.context.$1.customizepkg" 153 | }, 154 | { 155 | "match": ".*", 156 | "name": "invalid.illegal.context" 157 | } 158 | ] 159 | }, 160 | "pkgbuild-context-global": { 161 | "match": "\\b(global)\\b", 162 | "name": "keyword.other.context.$1.customizepkg" 163 | }, 164 | "pkgbuild-context-pkgbuild": { 165 | "match": "\\b(pkgbuild)\\b", 166 | "name": "keyword.other.context.$1.customizepkg" 167 | }, 168 | "remove": { 169 | "match": "^(remove|removeline)(#)([^#]*)(#)(.*)", 170 | "captures": { 171 | "1": { 172 | "name": "keyword.other.verb.$1.customizepkg" 173 | }, 174 | "2": { 175 | "name": "punctuation.separator.field" 176 | }, 177 | "3": { 178 | "name": "meta.section.$1.context.customizepkg", 179 | "patterns": [ 180 | { 181 | "include": "#pkgbuild-context-global" 182 | }, 183 | { 184 | "include": "#pkgbuild-context-directive" 185 | } 186 | ] 187 | }, 188 | "4": { 189 | "name": "punctuation.separator.field" 190 | }, 191 | "5": { 192 | "name": "meta.section.$3.$1 markup.deleted.$1" 193 | } 194 | } 195 | }, 196 | "replace": { 197 | "match": "^(replace)(#)([^#]*)(#)([^#]*)(#)(.*)", 198 | "captures": { 199 | "1": { 200 | "name": "keyword.other.verb.$1.customizepkg" 201 | }, 202 | "2": { 203 | "name": "punctuation.separator.field" 204 | }, 205 | "3": { 206 | "name": "meta.section.$1.context.customizepkg", 207 | "patterns": [ 208 | { 209 | "include": "#pkgbuild-context-global" 210 | }, 211 | { 212 | "include": "#pkgbuild-context-directive" 213 | } 214 | ] 215 | }, 216 | "4": { 217 | "name": "punctuation.separator.field" 218 | }, 219 | "5": { 220 | "name": "meta.section.$3.deleted.$1 markup.deleted.$1" 221 | }, 222 | "6": { 223 | "name": "punctuation.separator.field" 224 | }, 225 | "7": { 226 | "name": "meta.section.$3.inserted.$1 markup.inserted.$1" 227 | } 228 | } 229 | }, 230 | "unknown": { 231 | "patterns": [ 232 | { 233 | "match": "^([^#]+)(#)(.*)", 234 | "captures": { 235 | "1": { 236 | "name": "invalid.illegal.unknown.directive" 237 | }, 238 | "2": { 239 | "name": "punctuation.separator.field" 240 | }, 241 | "3": { 242 | "name": "meta.section.body.unknown.entry" 243 | } 244 | } 245 | }, 246 | { 247 | "match": ".*", 248 | "name": "invalid.illegal.unknown.entry" 249 | } 250 | ] 251 | } 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /extension/share/language/pacman-install-script.language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "#" 4 | }, 5 | "brackets": [ 6 | [ 7 | "{", 8 | "}" 9 | ], 10 | [ 11 | "[", 12 | "]" 13 | ], 14 | [ 15 | "(", 16 | ")" 17 | ] 18 | ], 19 | "autoClosingPairs": [ 20 | [ 21 | "{", 22 | "}" 23 | ], 24 | [ 25 | "[", 26 | "]" 27 | ], 28 | [ 29 | "(", 30 | ")" 31 | ], 32 | { 33 | "open": "\"", 34 | "close": "\"", 35 | "notIn": [ 36 | "string" 37 | ] 38 | }, 39 | { 40 | "open": "'", 41 | "close": "'", 42 | "notIn": [ 43 | "string" 44 | ] 45 | }, 46 | { 47 | "open": "`", 48 | "close": "`", 49 | "notIn": [ 50 | "string" 51 | ] 52 | } 53 | ], 54 | "surroundingPairs": [ 55 | [ 56 | "{", 57 | "}" 58 | ], 59 | [ 60 | "[", 61 | "]" 62 | ], 63 | [ 64 | "(", 65 | ")" 66 | ], 67 | [ 68 | "\"", 69 | "\"" 70 | ], 71 | [ 72 | "'", 73 | "'" 74 | ], 75 | [ 76 | "`", 77 | "`" 78 | ] 79 | ], 80 | "folding": { 81 | "markers": { 82 | "start": "^\\s*#\\s*#?region\\b.*", 83 | "end": "^\\s*#\\s*#?endregion\\b.*" 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /extension/share/language/pacman-install-script.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pacman-install-script", 3 | "scopeName": "source.shell.install-script.pacman", 4 | "uuid": "04125485-6333-4e94-aad4-6b5983795a02", 5 | "comment": "Pacman *.install script", 6 | "patterns": [ 7 | { 8 | "include": "source.shell" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /extension/src/extension.ts: -------------------------------------------------------------------------------- 1 | import { 2 | commands, 3 | Disposable, 4 | ExtensionContext, 5 | extensions, 6 | } from "vscode"; 7 | 8 | import { 9 | PACMAN_INSTALL_SCRIPT_SELECTOR, 10 | pacmanInstallScriptStatusItem, 11 | PKGBUILD_SELECTOR, 12 | pkgbuildStatusItem, 13 | } from "./language"; 14 | import log from "./log"; 15 | import { SubscriptionHelper } from "./shellcheck"; 16 | 17 | interface ExtensionPackageJson { 18 | "displayName": string, 19 | "version": string, 20 | } 21 | 22 | function packageJson(context: ExtensionContext): ExtensionPackageJson { 23 | return context.extension.packageJSON as ExtensionPackageJson; 24 | } 25 | 26 | export function activate(context: ExtensionContext) { 27 | commands.registerCommand("packaging.action.showLog", log.show, log); 28 | pacmanInstallScriptStatusItem.command = { 29 | command: "packaging.action.showLog", 30 | title: "Show extension log", 31 | }; 32 | pkgbuildStatusItem.command = { ...pacmanInstallScriptStatusItem.command }; 33 | 34 | const helpers: SubscriptionHelper[] = [ 35 | new SubscriptionHelper(context, PACMAN_INSTALL_SCRIPT_SELECTOR), 36 | new SubscriptionHelper(context, PKGBUILD_SELECTOR), 37 | ]; 38 | for (const helper of helpers) { 39 | let subscription: Disposable | null = helper.trySubscribe(); 40 | extensions.onDidChange((_) => { 41 | if (subscription) { 42 | subscription = helper.refresh(subscription); 43 | } else { 44 | subscription = helper.trySubscribe(); 45 | } 46 | }); 47 | } 48 | 49 | const { version } = packageJson(context); 50 | log.info(`Extension v${version} startup successful`); 51 | return {}; 52 | } 53 | 54 | export function deactivate() { 55 | return; 56 | } 57 | -------------------------------------------------------------------------------- /extension/src/language.ts: -------------------------------------------------------------------------------- 1 | import { DocumentFilter, languages, LanguageStatusItem } from "vscode"; 2 | 3 | export const PKGBUILD_SELECTOR: DocumentFilter = { language: "aur-pkgbuild" }; 4 | 5 | export const pkgbuildStatusItem: LanguageStatusItem = languages 6 | .createLanguageStatusItem( 7 | "aur-pkgbuild.status.item", 8 | PKGBUILD_SELECTOR, 9 | ); 10 | 11 | export const PACMAN_INSTALL_SCRIPT_SELECTOR: DocumentFilter = { 12 | language: "pacman-install-script", 13 | }; 14 | 15 | export const pacmanInstallScriptStatusItem: LanguageStatusItem = languages 16 | .createLanguageStatusItem( 17 | "pacman-install-script", 18 | PACMAN_INSTALL_SCRIPT_SELECTOR, 19 | ); 20 | -------------------------------------------------------------------------------- /extension/src/log.ts: -------------------------------------------------------------------------------- 1 | import { window } from "vscode"; 2 | 3 | export default window.createOutputChannel("Packaging", { log: true }); 4 | -------------------------------------------------------------------------------- /extension/src/shellcheck.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Disposable, 3 | DocumentFilter, 4 | Extension, 5 | ExtensionContext, 6 | extensions, 7 | } from "vscode"; 8 | 9 | import log from "./log"; 10 | 11 | const SHELLCHECK_EXTENSION: string = "timonwong.shellcheck"; 12 | 13 | export interface ShellCheckExtensionApiVersion1 { 14 | registerDocumentFilter: (documentFilter: DocumentFilter) => Disposable; 15 | } 16 | 17 | export class SubscriptionHelper { 18 | #context: ExtensionContext; 19 | #firstTry = true; 20 | #prefix: string; 21 | #selector: DocumentFilter; 22 | 23 | constructor(context: ExtensionContext, selector: DocumentFilter) { 24 | this.#context = context; 25 | this.#prefix = selector.language ?? JSON.stringify(selector); 26 | this.#selector = { ...selector }; 27 | } 28 | 29 | trySubscribe(): Disposable | null { 30 | const subscription: Disposable | null = this.#subscribe(); 31 | 32 | if (subscription) { 33 | if (this.#firstTry) { 34 | log.info(`${this.#prefix}: Connected to ShellCheck extension.`); 35 | } else { 36 | log.info(`${this.#prefix}:` 37 | + " ShellCheck extension has appeared. Connected."); 38 | } 39 | } else { 40 | // eslint-disable-next-line no-lonely-if 41 | if (this.#firstTry) { 42 | log.info(`${this.#prefix}: ShellCheck extension not active.`); 43 | } else { 44 | log.info(`${this.#prefix}:` 45 | + " Extensions have changed but still no sign of ShellCheck."); 46 | } 47 | } 48 | 49 | this.#firstTry = !!subscription; 50 | return subscription; 51 | } 52 | 53 | /* eslint-disable-next-line class-methods-use-this -- 54 | * Even though this method doesn’t use `this`, we leave it non-static 55 | * for better API consistency 56 | */ 57 | refresh(subscription: Disposable): Disposable | null { 58 | if (SubscriptionHelper.#api()) { 59 | log.info(`${this.#prefix}:` 60 | + " Extensions have changed but ShellCheck is still around."); 61 | return subscription; 62 | } 63 | log.info(`${this.#prefix}:` 64 | + "ShellCheck extension has gone away. Cleaning up."); 65 | subscription.dispose(); 66 | return null; 67 | } 68 | 69 | static #api(): ShellCheckExtensionApiVersion1 | null { 70 | const shellCheckExtension: Extension | undefined = 71 | extensions.getExtension(SHELLCHECK_EXTENSION); 72 | 73 | if (!shellCheckExtension?.exports 74 | || !(shellCheckExtension.exports instanceof Object) 75 | || !("apiVersion1" in shellCheckExtension.exports)) { 76 | log.error( 77 | "The ShellCheck extension is active but did not provide an API surface." 78 | + " Is the ShellCheck extension outdated?", 79 | ); 80 | return null; 81 | } 82 | const { apiVersion1 } = shellCheckExtension.exports as 83 | { apiVersion1: ShellCheckExtensionApiVersion1 }; 84 | return apiVersion1; 85 | } 86 | 87 | #subscribe(): Disposable | null { 88 | const api = SubscriptionHelper.#api(); 89 | if (!api) { 90 | return null; 91 | } 92 | 93 | const subscription: Disposable = api.registerDocumentFilter(this.#selector); 94 | this.#context.subscriptions.push(subscription); 95 | return subscription; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /extension/src/time.ts: -------------------------------------------------------------------------------- 1 | import { promisify } from "node:util"; 2 | 3 | const dateTimeFormat: Intl.DateTimeFormat = new Intl.DateTimeFormat([], { 4 | dateStyle: "long", 5 | timeStyle: "long", 6 | }); 7 | 8 | export function getCurrentTimestamp(): string { 9 | return dateTimeFormat.format(new Date()); 10 | } 11 | 12 | export async function sleep( 13 | durationMs: number, 14 | ): Promise> { 15 | return await promisify(setTimeout)(durationMs); 16 | } 17 | -------------------------------------------------------------------------------- /extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "declarationDir": "types", 5 | "downlevelIteration": true, 6 | "esModuleInterop": true, 7 | "inlineSources": true, 8 | "inlineSourceMap": true, 9 | "module": "CommonJS", 10 | "moduleResolution": "Node", 11 | "noImplicitAny": true, 12 | "outDir": "work/tsc-out", 13 | "resolveJsonModule": true, 14 | "skipLibCheck": false, 15 | "strictNullChecks": true, 16 | "target": "ES2022" 17 | }, 18 | "include": [ 19 | "src" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-packaging", 3 | "license": "SEE LICENSE IN README.md", 4 | "engines": { 5 | "node": "^20.0.0" 6 | }, 7 | "comments": { 8 | "devDependencies": { 9 | "@types/node": "Keep this pinned to the Node.js major version that ships with VS Code.", 10 | "@types/vscode": "For details, see section *Upgrading the VS Code API version* in `README.md`.", 11 | "@typescript-eslint/eslint-plugin": "Keep this pinned to 7.x unless eslint gets unpinned.", 12 | "@typescript-eslint/parser": "Keep this pinned to 7.x unless eslint gets unpinned.", 13 | "@vscode/vsce": "Private patch for Yarn v4 compatibility. Keep in sync with the version of the `@vscode/vsce` dependency. Temporary note: Keep this pinned to 2.21.0 until an updated cwd patch is available.", 14 | "@yarnpkg/sdks": "Before upgrading to a newer major version, check Node.js version compatibility. When bumping the major version, keep it in sync with `yarn set version` invocations.", 15 | "eslint": "Keep this pinned to 8.x unless the configuration is migrated.", 16 | "typescript": "Keep this pinned to 5.5.x as long as yarn lint prints a warning about typescript-estree." 17 | } 18 | }, 19 | "devDependencies": { 20 | "@types/jest": "^29.5.12", 21 | "@yarnpkg/sdks": "^3.1.0", 22 | "typescript": "<=5.5.x" 23 | }, 24 | "resolutions": { 25 | "@vscode/vsce@^2.21.1": "patch:@vscode/vsce@npm:2.21.1#./.yarn/patches/@vscode-vsce-npm-2.21.1.patch" 26 | }, 27 | "scripts": { 28 | "clean": "yarn workspace extension clean && true yarn workspace packaging clean", 29 | "clean-install": "yarn install && git checkout -- .vscode/settings.json '.yarn/*/LICENSE'", 30 | "compile": "true yarn workspace packaging compile && yarn workspace extension compile", 31 | "lint": "true yarn workspace packaging lint && yarn workspace extension lint", 32 | "package": "true yarn workspace packaging compile && yarn workspace extension package", 33 | "postinstall": "yarn sdks vscode", 34 | "test": "true yarn workspace packaging test", 35 | "upgrade-all": "printf >&2 '%s\\n\\t%s\\n' 'Run the following command line manually:' 'yarn set version 4 && yarn install && yarn upgrade-packages' && false", 36 | "upgrade-lockfile": "yarn up -R '**' && yarn clean-install", 37 | "upgrade-packages": "yarn up '**' '@types/node@<=20.x' '@types/vscode@=1.92' '@typescript-eslint/eslint-plugin@<=7.x' '@typescript-eslint/parser@<=7.x' '@vscode/vsce@^2.21.1' '@yarnpkg/sdks@^3.1.0' 'eslint@<=8.x' 'typescript@<=5.5.x' && yarn up -R '**' && yarn clean-install", 38 | "upgrade-yarn-itself": "printf >&2 '%s\\n\\t%s\\n' 'Run the following command line manually:' 'yarn set version 4 && yarn install && yarn clean-install' && false" 39 | }, 40 | "workspaces": [ 41 | "extension", 42 | "packaging" 43 | ], 44 | "packageManager": "yarn@4.4.1" 45 | } 46 | -------------------------------------------------------------------------------- /packaging/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | env: 2 | node: true 3 | extends: 4 | - eslint:recommended 5 | - plugin:@typescript-eslint/recommended-type-checked 6 | - plugin:@typescript-eslint/stylistic-type-checked 7 | ignorePatterns: 8 | - lib/ 9 | - types/ 10 | overrides: 11 | - files: "**/*.test.ts" 12 | env: 13 | jest/globals: true 14 | plugins: 15 | - jest 16 | parserOptions: 17 | project: 18 | - tsconfig.linting.json 19 | rules: 20 | max-lines-per-function: 0 21 | parser: "@typescript-eslint/parser" 22 | parserOptions: 23 | ecmaFeatures: 24 | impliedStrict: true 25 | ecmaVersion: 2022 26 | project: 27 | - tsconfig.json 28 | plugins: 29 | - "@typescript-eslint" 30 | root: true 31 | rules: 32 | array-bracket-spacing: 1 33 | arrow-spacing: 1 34 | block-spacing: 1 35 | brace-style: 1 36 | camelcase: 1 37 | class-methods-use-this: 1 38 | comma-dangle: [1, always-multiline] 39 | comma-spacing: 1 40 | comma-style: 1 41 | complexity: 1 42 | computed-property-spacing: 1 43 | consistent-return: 1 44 | consistent-this: 1 45 | default-case-last: 1 46 | default-case: 2 47 | dot-location: [1, property] 48 | dot-notation: [1, { allowKeywords: false }] 49 | eqeqeq: 1 50 | func-call-spacing: 1 51 | generator-star-spacing: [1, before] 52 | guard-for-in: 1 53 | indent: [1, 2] 54 | key-spacing: 1 55 | linebreak-style: 2 56 | lines-between-class-members: [1, always, { exceptAfterSingleLine: true }] 57 | logical-assignment-operators: [1, always, { enforceForIfStatements: true }] 58 | max-depth: 1 59 | max-len: 60 | - 1 61 | - code: 80 62 | ignorePattern: ^\s*/[/*] eslint-disable 63 | ignoreUrls: true 64 | max-lines-per-function: 1 65 | max-lines: 1 66 | newline-per-chained-call: [1, { ignoreChainWithDepth: 2 }] 67 | no-alert: 2 68 | no-console: 2 69 | no-implied-eval: 1 70 | no-invalid-this: 2 71 | no-lone-blocks: 1 72 | no-lonely-if: 1 73 | no-loop-func: 1 74 | no-mixed-operators: 1 75 | no-multi-assign: 1 76 | no-multi-spaces: 1 77 | no-multiple-empty-lines: [1, { max: 1 }] 78 | no-negated-condition: 1 79 | no-octal-escape: 2 80 | no-return-assign: 1 81 | no-self-compare: 1 82 | no-shadow: 1 83 | no-tabs: 2 84 | no-template-curly-in-string: 1 85 | no-throw-literal: 2 86 | no-trailing-spaces: 1 87 | no-undefined: 1 88 | no-unexpected-multiline: 1 89 | no-unused-expressions: 1 90 | 91 | # For compatibility with typescript-eslint 92 | no-unused-vars: 0 93 | 94 | no-useless-concat: 1 95 | no-var: 1 96 | no-whitespace-before-property: 1 97 | object-shorthand: 1 98 | operator-assignment: 1 99 | prefer-const: 1 100 | prefer-destructuring: 1 101 | prefer-exponentiation-operator: 1 102 | prefer-named-capture-group: 1 103 | prefer-object-has-own: 1 104 | prefer-object-spread: 1 105 | prefer-regex-literals: 1 106 | prefer-rest-params: 1 107 | prefer-spread: 1 108 | prefer-template: 1 109 | quote-props: [1, as-needed] 110 | quotes: 1 111 | radix: 1 112 | require-await: 1 113 | require-yield: 1 114 | rest-spread-spacing: 1 115 | semi-spacing: 1 116 | semi-style: 1 117 | sort-imports: [1, { ignoreCase: true, ignoreDeclarationSort: true }] 118 | sort-vars: 1 119 | space-before-blocks: 1 120 | space-before-function-paren: [1, { named: never }] 121 | space-in-parens: 1 122 | space-infix-ops: 1 123 | space-unary-ops: 1 124 | spaced-comment: 1 125 | unicode-bom: 2 126 | yoda: 1 127 | 128 | "@typescript-eslint/array-type": 1 129 | 130 | # In VS Code, this allows developers to manually specify 131 | # inferrable types so the distracting inline hints go away 132 | "@typescript-eslint/no-inferrable-types": 0 133 | 134 | # https://github.com/typescript-eslint/typescript-eslint/issues/4912 135 | "@typescript-eslint/no-unsafe-argument": 0 136 | "@typescript-eslint/no-unsafe-assignment": 0 137 | "@typescript-eslint/no-unsafe-member-access": 0 138 | 139 | "@typescript-eslint/no-unused-vars": [1, { argsIgnorePattern: ^_, varsIgnorePattern: ^_ }] 140 | "@typescript-eslint/unbound-method": 0 141 | -------------------------------------------------------------------------------- /packaging/.gitignore: -------------------------------------------------------------------------------- 1 | /coverage/ 2 | /dist/ 3 | /lib/ 4 | /types/ 5 | -------------------------------------------------------------------------------- /packaging/jest.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "clearMocks": true, 3 | "collectCoverage": true, 4 | "coverageDirectory": "coverage", 5 | "coverageProvider": "v8", 6 | "showSeed": true, 7 | "transform": { 8 | "^.+\\.tsx?$": [ 9 | "ts-jest", 10 | {} 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packaging/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "packaging", 3 | "engines": { 4 | "node": ">= 20.0.0" 5 | }, 6 | "files": [ 7 | "/lib/", 8 | "/types/" 9 | ], 10 | "main": "./lib/index.js", 11 | "types": "./types/index.d.ts", 12 | "comments": { 13 | "devDependencies": { 14 | "@types/node": "Keep this pinned to the Node.js major version specified in `engines`" 15 | } 16 | }, 17 | "devDependencies": { 18 | "@types/jest": "^29.5.12", 19 | "@types/node": "<=20.x", 20 | "@types/tmp": "^0.2.6", 21 | "@typescript-eslint/eslint-plugin": "<=7.x", 22 | "@typescript-eslint/parser": "<=7.x", 23 | "del-cli": "^5.1.0", 24 | "eslint": "<=8.x", 25 | "eslint-plugin-jest": "^28.8.3", 26 | "jest": "^29.7.0", 27 | "semver": "^7.6.3", 28 | "source-map-support": "^0.5.21", 29 | "ts-jest": "^29.2.5", 30 | "ts-node": "^10.9.2", 31 | "typescript": "<=5.5.x" 32 | }, 33 | "scripts": { 34 | "clean": "yarn run -B del dist lib types", 35 | "compile": "yarn run -B tsc", 36 | "lint": "yarn run -B eslint --max-warnings 0 src", 37 | "repatch": "git add -- package.json && yarn patch-commit -s \"$1\" && git checkout -- package.json && yarn clean-install", 38 | "test": "yarn run -B tsc && yarn run -B jest" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packaging/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "declarationDir": "types", 5 | "downlevelIteration": true, 6 | "esModuleInterop": true, 7 | "inlineSources": true, 8 | "inlineSourceMap": true, 9 | "module": "CommonJS", 10 | "moduleResolution": "Node", 11 | "noImplicitAny": true, 12 | "outDir": "lib", 13 | "resolveJsonModule": true, 14 | "skipLibCheck": false, 15 | "strictNullChecks": true, 16 | "target": "ES2022" 17 | }, 18 | "include": [ 19 | "src" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packaging/tsconfig.linting.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": [ 4 | "src", 5 | "test" 6 | ] 7 | } 8 | --------------------------------------------------------------------------------