├── .editorconfig ├── .eslintrc.json ├── .github ├── codeql │ └── codeql-config.yml ├── dependabot.yml ├── labels.yml └── workflows │ ├── code-ql.yml │ ├── continuous-integration.yml │ ├── dependabot-automerge.yaml │ ├── labels.yml │ └── release.yml ├── .gitignore ├── .nvmrc ├── .vscode └── settings.json ├── CODEOWNERS ├── LICENSE ├── README.md ├── action.yml ├── devcard.png ├── devcard.svg ├── dist ├── 886.index.js ├── index.js └── license.txt ├── package.json ├── pnpm-lock.yaml ├── src └── index.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | ; Editor config 2 | root = true 3 | 4 | [*] 5 | indent_style = tab 6 | indent_size = 4 7 | insert_final_newline = true 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | end_of_ine = lf 11 | 12 | [*.{yml,yaml}] 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [{package,tsconfig}.json] 17 | indent_style = space 18 | indent_size = 2 19 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 2021, 6 | "sourceType": "module", 7 | "project": "./tsconfig.json", 8 | "warnOnUnsupportedTypeScriptVersion": true 9 | }, 10 | "plugins": [ 11 | "@typescript-eslint" 12 | ], 13 | "extends": [ 14 | "plugin:@typescript-eslint/recommended", 15 | "plugin:prettier/recommended" 16 | ], 17 | "globals": { 18 | "global": true 19 | }, 20 | "settings": { 21 | "react": { 22 | "version": "detect" 23 | } 24 | }, 25 | "ignorePatterns": ["**/*.min.*", "**/dist/**"], 26 | "rules": { 27 | "prettier/prettier": [ 28 | "error", 29 | { 30 | "semi": false, 31 | "singleQuote": true, 32 | "tabWidth": 4, 33 | "trailingComma": "all", 34 | "useTabs": true, 35 | "printWidth": 127 36 | } 37 | ], 38 | "@typescript-eslint/no-empty-function": "warn", 39 | "@typescript-eslint/ban-ts-comment": "warn", 40 | "@typescript-eslint/no-explicit-any": "warn", 41 | "@typescript-eslint/explicit-module-boundary-types": "warn" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /.github/codeql/codeql-config.yml: -------------------------------------------------------------------------------- 1 | paths: 2 | - src 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: github-actions 5 | directory: / 6 | schedule: 7 | interval: monthly 8 | 9 | - package-ecosystem: npm 10 | directory: / 11 | schedule: 12 | interval: monthly 13 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | ## more info https://github.com/crazy-max/ghaction-github-labeler 2 | - # automerge 3 | name: ":bell: automerge" 4 | color: "8f4fbc" 5 | description: "" 6 | - # bot 7 | name: ":robot: bot" 8 | color: "69cde9" 9 | description: "" 10 | - # bug 11 | name: ":bug: bug" 12 | color: "b60205" 13 | description: "" 14 | - # dependencies 15 | name: ":game_die: dependencies" 16 | color: "0366d6" 17 | description: "" 18 | - # documentation 19 | name: ":memo: documentation" 20 | color: "c5def5" 21 | description: "" 22 | - # duplicate 23 | name: ":busts_in_silhouette: duplicate" 24 | color: "cccccc" 25 | description: "" 26 | - # enhancement 27 | name: ":sparkles: enhancement" 28 | color: "0054ca" 29 | description: "" 30 | - # feature request 31 | name: ":bulb: feature request" 32 | color: "0e8a16" 33 | description: "" 34 | - # feedback 35 | name: ":mega: feedback" 36 | color: "03a9f4" 37 | description: "" 38 | - # future maybe 39 | name: ":rocket: future maybe" 40 | color: "fef2c0" 41 | description: "" 42 | - # good first issue 43 | name: ":hatching_chick: good first issue" 44 | color: "7057ff" 45 | description: "" 46 | - # help wanted 47 | name: ":pray: help wanted" 48 | color: "4caf50" 49 | description: "" 50 | - # hold 51 | name: ":hand: hold" 52 | color: "24292f" 53 | description: "" 54 | - # invalid 55 | name: ":no_entry_sign: invalid" 56 | color: "e6e6e6" 57 | description: "" 58 | - # maybe bug 59 | name: ":interrobang: maybe bug" 60 | color: "ff5722" 61 | description: "" 62 | - # needs more info 63 | name: ":thinking: needs more info" 64 | color: "795548" 65 | description: "" 66 | - # question 67 | name: ":question: question" 68 | color: "3f51b5" 69 | description: "" 70 | - # upstream 71 | name: ":eyes: upstream" 72 | color: "fbca04" 73 | description: "" 74 | - # wontfix 75 | name: ":coffin: wontfix" 76 | color: "ffffff" 77 | description: "" 78 | -------------------------------------------------------------------------------- /.github/workflows/code-ql.yml: -------------------------------------------------------------------------------- 1 | name: CodeQL 2 | 3 | on: 4 | push: 5 | branches: 6 | - develop 7 | - main 8 | pull_request: 9 | branches: 10 | - develop 11 | schedule: 12 | # run every day at 1AM 13 | - cron: "0 1 * * *" 14 | 15 | jobs: 16 | analyze: 17 | name: Analyze 18 | runs-on: ubuntu-20.04 19 | 20 | steps: 21 | - name: Checkout repository 22 | uses: actions/checkout@v4 23 | 24 | - name: Initialize CodeQL 25 | uses: github/codeql-action/init@v3 26 | with: 27 | languages: javascript 28 | config-file: ./.github/codeql/codeql-config.yml 29 | 30 | - name: Perform CodeQL Analysis 31 | uses: github/codeql-action/analyze@v3 32 | -------------------------------------------------------------------------------- /.github/workflows/continuous-integration.yml: -------------------------------------------------------------------------------- 1 | name: continuous-integration 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | - develop 9 | - feature/** 10 | 11 | env: 12 | CI: true 13 | 14 | jobs: 15 | lint-build-test: 16 | runs-on: ubuntu-20.04 17 | steps: 18 | - 19 | name: Checkout code 20 | uses: actions/checkout@v4 21 | 22 | - name: Enable Corepack 23 | run: corepack enable 24 | 25 | - uses: actions/setup-node@v4.4.0 26 | with: 27 | node-version: 22 28 | cache: pnpm 29 | 30 | - name: Cache node_modules 31 | id: cache-node_modules 32 | uses: actions/cache@v4.2.2 33 | with: 34 | path: node_modules 35 | key: ${{ runner.os }}-node_modules-${{ hashFiles('**/pnpm-lock.yaml') }} 36 | restore-keys: | 37 | ${{ runner.os }}-node_modules- 38 | ${{ runner.os }}- 39 | 40 | - name: Install dependencies 41 | if: steps.cache-node_modules.outputs.cache-hit != 'true' 42 | run: | 43 | pnpm install --frozen-lockfile 44 | 45 | - name: Lint 46 | run: | 47 | pnpm lint 48 | 49 | - name: Build 50 | run: | 51 | pnpm build 52 | 53 | - name: devcard.png 54 | uses: ./ 55 | with: 56 | user_id: XDCZD-PHG 57 | commit_filename: devcard.png 58 | commit_branch: main 59 | dryrun: true 60 | 61 | dependabot: 62 | needs: 63 | - lint-build-test 64 | uses: ./.github/workflows/dependabot-automerge.yaml 65 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-automerge.yaml: -------------------------------------------------------------------------------- 1 | name: Approve and enable auto-merge for Dependabot PRs 2 | 3 | on: 4 | workflow_call: 5 | pull_request: 6 | paths: 7 | - '.github/workflows/dependabot-automerge.yaml' 8 | 9 | permissions: 10 | pull-requests: write 11 | contents: write 12 | 13 | jobs: 14 | dependabot: 15 | runs-on: ubuntu-latest 16 | if: ${{ github.actor == 'dependabot[bot]' }} 17 | steps: 18 | - name: Dependabot metadata 19 | id: metadata 20 | uses: dependabot/fetch-metadata@v2.2.0 21 | with: 22 | github-token: "${{ secrets.GITHUB_TOKEN }}" 23 | 24 | # Direct dev dependencies 25 | - name: Approve PR and auto-merge all dev-dependencies 26 | if: ${{contains(steps.metadata.outputs.dependency-type, 'direct:development')}} 27 | env: 28 | PR_URL: ${{github.event.pull_request.html_url}} 29 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 30 | run: | 31 | gh pr review --approve "$PR_URL" 32 | gh pr merge --auto --squash "$PR_URL" 33 | 34 | # Direct prod dependencies 35 | - name: Approve PR and auto-merge prod-dependencies (only patches) 36 | if: ${{contains(steps.metadata.outputs.dependency-type, 'direct:production') && steps.metadata.outputs.update-type == 'version-update:semver-patch'}} 37 | env: 38 | PR_URL: ${{github.event.pull_request.html_url}} 39 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 40 | run: | 41 | gh pr review --approve "$PR_URL" 42 | gh pr merge --auto --squash "$PR_URL" 43 | 44 | # Indirect dependencies 45 | - name: Approve PR and auto-merge all indirect dependencies 46 | if: ${{contains(steps.metadata.outputs.dependency-type, 'indirect') && steps.metadata.outputs.update-type == 'version-update:semver-patch'}} 47 | env: 48 | PR_URL: ${{github.event.pull_request.html_url}} 49 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 50 | run: | 51 | gh pr review --approve "$PR_URL" 52 | gh pr merge --auto --squash "$PR_URL" 53 | -------------------------------------------------------------------------------- /.github/workflows/labels.yml: -------------------------------------------------------------------------------- 1 | name: labels 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | paths: 9 | - .github/labels.yml 10 | - .github/workflows/labels.yml 11 | 12 | jobs: 13 | labeler: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | 19 | - name: Run Labeler 20 | uses: crazy-max/ghaction-github-labeler@v5.1.0 21 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | run-name: "release '${{ github.event.inputs.version }}' version by @${{ github.actor }}" 3 | 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | version: 8 | description: 'Version' 9 | required: true 10 | default: 'patch' 11 | type: choice 12 | options: 13 | - 'major' 14 | - 'minor' 15 | - 'patch' 16 | 17 | jobs: 18 | build: 19 | runs-on: ubuntu-20.04 20 | permissions: 21 | id-token: write # Enable OIDC 22 | pull-requests: write 23 | contents: write 24 | 25 | steps: 26 | - name: Checkout code 27 | uses: actions/checkout@v4 28 | 29 | - uses: chainguard-dev/actions/setup-gitsign@main 30 | 31 | - name: Enable Corepack 32 | run: corepack enable 33 | 34 | - uses: actions/setup-node@v4.4.0 35 | with: 36 | node-version: 22 37 | cache: pnpm 38 | 39 | - uses: pnpm/action-setup@v4.0.0 40 | 41 | - name: Cache node_modules 42 | id: cache-node_modules 43 | uses: actions/cache@v4.2.2 44 | with: 45 | path: node_modules 46 | key: ${{ runner.os }}-node_modules-${{ hashFiles('**/pnpm-lock.yaml') }} 47 | restore-keys: | 48 | ${{ runner.os }}-node_modules- 49 | ${{ runner.os }}- 50 | 51 | - name: Install dependencies 52 | if: steps.cache-node_modules.outputs.cache-hit != 'true' 53 | run: | 54 | pnpm install --frozen-lockfile 55 | 56 | - name: Setup git 57 | run: | 58 | git config --global tag.gpgsign true 59 | 60 | - name: Bump version 61 | run: | 62 | OLD_VERSION=$(node -p "require('./package.json').version") 63 | npm version ${{ github.event.inputs.version }} --no-git-tag-version 64 | VERSION=$(node -p "require('./package.json').version") 65 | sed -i "s/$OLD_VERSION/$VERSION/g" README.md 66 | 67 | - name: Prune dist 68 | run: | 69 | rm -rf dist 70 | 71 | - name: Build 72 | run: | 73 | pnpm build 74 | git add -A dist 75 | 76 | - name: Publish 77 | env: 78 | GH_TOKEN: ${{ github.token }} 79 | run: | 80 | VERSION=$(node -p "require('./package.json').version") 81 | git commit -m "release: $VERSION" -a 82 | git push 83 | 84 | gh release create $VERSION --generate-notes 85 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/git,vim,node,linux,macos,windows,sublimetext,visualstudiocode,intellij+all 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=git,vim,node,linux,macos,windows,sublimetext,visualstudiocode,intellij+all 4 | 5 | ### Git ### 6 | # Created by git for backups. To disable backups in Git: 7 | # $ git config --global mergetool.keepBackup false 8 | *.orig 9 | 10 | # Created by git when using merge tools for conflicts 11 | *.BACKUP.* 12 | *.BASE.* 13 | *.LOCAL.* 14 | *.REMOTE.* 15 | *_BACKUP_*.txt 16 | *_BASE_*.txt 17 | *_LOCAL_*.txt 18 | *_REMOTE_*.txt 19 | 20 | ### Intellij+all ### 21 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 22 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 23 | 24 | # User-specific stuff 25 | .idea/**/workspace.xml 26 | .idea/**/tasks.xml 27 | .idea/**/usage.statistics.xml 28 | .idea/**/dictionaries 29 | .idea/**/shelf 30 | 31 | # AWS User-specific 32 | .idea/**/aws.xml 33 | 34 | # Generated files 35 | .idea/**/contentModel.xml 36 | 37 | # Sensitive or high-churn files 38 | .idea/**/dataSources/ 39 | .idea/**/dataSources.ids 40 | .idea/**/dataSources.local.xml 41 | .idea/**/sqlDataSources.xml 42 | .idea/**/dynamic.xml 43 | .idea/**/uiDesigner.xml 44 | .idea/**/dbnavigator.xml 45 | 46 | # Gradle 47 | .idea/**/gradle.xml 48 | .idea/**/libraries 49 | 50 | # Gradle and Maven with auto-import 51 | # When using Gradle or Maven with auto-import, you should exclude module files, 52 | # since they will be recreated, and may cause churn. Uncomment if using 53 | # auto-import. 54 | # .idea/artifacts 55 | # .idea/compiler.xml 56 | # .idea/jarRepositories.xml 57 | # .idea/modules.xml 58 | # .idea/*.iml 59 | # .idea/modules 60 | # *.iml 61 | # *.ipr 62 | 63 | # CMake 64 | cmake-build-*/ 65 | 66 | # Mongo Explorer plugin 67 | .idea/**/mongoSettings.xml 68 | 69 | # File-based project format 70 | *.iws 71 | 72 | # IntelliJ 73 | out/ 74 | 75 | # mpeltonen/sbt-idea plugin 76 | .idea_modules/ 77 | 78 | # JIRA plugin 79 | atlassian-ide-plugin.xml 80 | 81 | # Cursive Clojure plugin 82 | .idea/replstate.xml 83 | 84 | # Crashlytics plugin (for Android Studio and IntelliJ) 85 | com_crashlytics_export_strings.xml 86 | crashlytics.properties 87 | crashlytics-build.properties 88 | fabric.properties 89 | 90 | # Editor-based Rest Client 91 | .idea/httpRequests 92 | 93 | # Android studio 3.1+ serialized cache file 94 | .idea/caches/build_file_checksums.ser 95 | 96 | ### Intellij+all Patch ### 97 | # Ignores the whole .idea folder and all .iml files 98 | # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 99 | 100 | .idea/ 101 | 102 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 103 | 104 | *.iml 105 | modules.xml 106 | .idea/misc.xml 107 | *.ipr 108 | 109 | # Sonarlint plugin 110 | .idea/sonarlint 111 | 112 | ### Linux ### 113 | *~ 114 | 115 | # temporary files which can be created if a process still has a handle open of a deleted file 116 | .fuse_hidden* 117 | 118 | # KDE directory preferences 119 | .directory 120 | 121 | # Linux trash folder which might appear on any partition or disk 122 | .Trash-* 123 | 124 | # .nfs files are created when an open file is removed but is still being accessed 125 | .nfs* 126 | 127 | ### macOS ### 128 | # General 129 | .DS_Store 130 | .AppleDouble 131 | .LSOverride 132 | 133 | # Icon must end with two \r 134 | Icon 135 | 136 | # Thumbnails 137 | ._* 138 | 139 | # Files that might appear in the root of a volume 140 | .DocumentRevisions-V100 141 | .fseventsd 142 | .Spotlight-V100 143 | .TemporaryItems 144 | .Trashes 145 | .VolumeIcon.icns 146 | .com.apple.timemachine.donotpresent 147 | 148 | # Directories potentially created on remote AFP share 149 | .AppleDB 150 | .AppleDesktop 151 | Network Trash Folder 152 | Temporary Items 153 | .apdisk 154 | 155 | ### Node ### 156 | # Logs 157 | logs 158 | *.log 159 | npm-debug.log* 160 | yarn-debug.log* 161 | yarn-error.log* 162 | lerna-debug.log* 163 | .pnpm-debug.log* 164 | 165 | # Diagnostic reports (https://nodejs.org/api/report.html) 166 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 167 | 168 | # Runtime data 169 | pids 170 | *.pid 171 | *.seed 172 | *.pid.lock 173 | 174 | # Directory for instrumented libs generated by jscoverage/JSCover 175 | lib-cov 176 | 177 | # Coverage directory used by tools like istanbul 178 | coverage 179 | *.lcov 180 | 181 | # nyc test coverage 182 | .nyc_output 183 | 184 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 185 | .grunt 186 | 187 | # Bower dependency directory (https://bower.io/) 188 | bower_components 189 | 190 | # node-waf configuration 191 | .lock-wscript 192 | 193 | # Compiled binary addons (https://nodejs.org/api/addons.html) 194 | build/Release 195 | 196 | # Dependency directories 197 | node_modules/ 198 | jspm_packages/ 199 | 200 | # Snowpack dependency directory (https://snowpack.dev/) 201 | web_modules/ 202 | 203 | # TypeScript cache 204 | *.tsbuildinfo 205 | 206 | # Optional npm cache directory 207 | .npm 208 | 209 | # Optional eslint cache 210 | .eslintcache 211 | 212 | # Microbundle cache 213 | .rpt2_cache/ 214 | .rts2_cache_cjs/ 215 | .rts2_cache_es/ 216 | .rts2_cache_umd/ 217 | 218 | # Optional REPL history 219 | .node_repl_history 220 | 221 | # Output of 'npm pack' 222 | *.tgz 223 | 224 | # Yarn Integrity file 225 | .yarn-integrity 226 | 227 | # dotenv environment variables file 228 | .env 229 | .env.test 230 | .env.production 231 | 232 | # parcel-bundler cache (https://parceljs.org/) 233 | .cache 234 | .parcel-cache 235 | 236 | # Next.js build output 237 | .next 238 | out 239 | 240 | # Nuxt.js build / generate output 241 | .nuxt 242 | dist 243 | 244 | # Gatsby files 245 | .cache/ 246 | # Comment in the public line in if your project uses Gatsby and not Next.js 247 | # https://nextjs.org/blog/next-9-1#public-directory-support 248 | # public 249 | 250 | # vuepress build output 251 | .vuepress/dist 252 | 253 | # Serverless directories 254 | .serverless/ 255 | 256 | # FuseBox cache 257 | .fusebox/ 258 | 259 | # DynamoDB Local files 260 | .dynamodb/ 261 | 262 | # TernJS port file 263 | .tern-port 264 | 265 | # Stores VSCode versions used for testing VSCode extensions 266 | .vscode-test 267 | 268 | # yarn v2 269 | .yarn/cache 270 | .yarn/unplugged 271 | .yarn/build-state.yml 272 | .yarn/install-state.gz 273 | .pnp.* 274 | 275 | ### SublimeText ### 276 | # Cache files for Sublime Text 277 | *.tmlanguage.cache 278 | *.tmPreferences.cache 279 | *.stTheme.cache 280 | 281 | # Workspace files are user-specific 282 | *.sublime-workspace 283 | 284 | # Project files should be checked into the repository, unless a significant 285 | # proportion of contributors will probably not be using Sublime Text 286 | # *.sublime-project 287 | 288 | # SFTP configuration file 289 | sftp-config.json 290 | sftp-config-alt*.json 291 | 292 | # Package control specific files 293 | Package Control.last-run 294 | Package Control.ca-list 295 | Package Control.ca-bundle 296 | Package Control.system-ca-bundle 297 | Package Control.cache/ 298 | Package Control.ca-certs/ 299 | Package Control.merged-ca-bundle 300 | Package Control.user-ca-bundle 301 | oscrypto-ca-bundle.crt 302 | bh_unicode_properties.cache 303 | 304 | # Sublime-github package stores a github token in this file 305 | # https://packagecontrol.io/packages/sublime-github 306 | GitHub.sublime-settings 307 | 308 | ### Vim ### 309 | # Swap 310 | [._]*.s[a-v][a-z] 311 | !*.svg # comment out if you don't need vector files 312 | [._]*.sw[a-p] 313 | [._]s[a-rt-v][a-z] 314 | [._]ss[a-gi-z] 315 | [._]sw[a-p] 316 | 317 | # Session 318 | Session.vim 319 | Sessionx.vim 320 | 321 | # Temporary 322 | .netrwhist 323 | # Auto-generated tag files 324 | tags 325 | # Persistent undo 326 | [._]*.un~ 327 | 328 | ### VisualStudioCode ### 329 | .vscode/* 330 | !.vscode/settings.json 331 | !.vscode/tasks.json 332 | !.vscode/launch.json 333 | !.vscode/extensions.json 334 | *.code-workspace 335 | 336 | # Local History for Visual Studio Code 337 | .history/ 338 | 339 | ### VisualStudioCode Patch ### 340 | # Ignore all local history of files 341 | .history 342 | .ionide 343 | 344 | ### Windows ### 345 | # Windows thumbnail cache files 346 | Thumbs.db 347 | Thumbs.db:encryptable 348 | ehthumbs.db 349 | ehthumbs_vista.db 350 | 351 | # Dump file 352 | *.stackdump 353 | 354 | # Folder config file 355 | [Dd]esktop.ini 356 | 357 | # Recycle Bin used on file shares 358 | $RECYCLE.BIN/ 359 | 360 | # Windows Installer files 361 | *.cab 362 | *.msi 363 | *.msix 364 | *.msm 365 | *.msp 366 | 367 | # Windows shortcuts 368 | *.lnk 369 | 370 | # End of https://www.toptal.com/developers/gitignore/api/git,vim,node,linux,macos,windows,sublimetext,visualstudiocode,intellij+all 371 | 372 | !dist 373 | !dist/** 374 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v22 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } 4 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @omBratteng 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021, Ole-Martin Bratteng 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitHub Action for fetching the devcard from [daily.dev](https://api.daily.dev/get?r=omBratteng) 2 | 3 | [![GitHub](https://img.shields.io/github/license/dailydotdev/action-devcard)](LICENSE) 4 | [![GitHub Workflow Status (event)](https://img.shields.io/github/workflow/status/dailydotdev/action-devcard/continuous-integration?event=push&label=continuous-integration&logo=github)](https://github.com/dailydotdev/action-devcard/actions/workflows/continuous-integration.yml) 5 | [![GitHub release (latest by date)](https://img.shields.io/github/v/release/dailydotdev/action-devcard?logo=github)](https://github.com/dailydotdev/action-devcard/releases/latest) 6 | 7 | ## Example usage 8 | 9 | ```yaml 10 | jobs: 11 | devcard: 12 | runs-on: ubuntu-latest 13 | permissions: 14 | contents: write 15 | steps: 16 | - name: devcard 17 | uses: dailydotdev/action-devcard@3.2.1 18 | with: 19 | user_id: ${{ secrets.USER_ID }} 20 | ``` 21 | 22 | ## Action options 23 | 24 | ### Required 25 | 26 | - `user_id`: this is the unique id of the devcard, it can be found in the URL of the devcard or [here](https://app.daily.dev/api/id). 27 | - e.g. `https://api.daily.dev/devcards/v2/0b156485612243bfa39093.2.171e276.png` where the user_id is `0b156485612243bfa39093.2.171e276` 28 | - Can be found at [https://app.daily.dev/api/id](https://app.daily.dev/api/id) 29 | 30 | ### Optional 31 | 32 | - `type`: Configure orientation for devcard 33 | - `default`: Vertical (Default) 34 | - `wide`: Horizontal 35 | - `token`: GitHub Token used to commit the devcard 36 | - `commit_branch`: The branch to commit the devcard to. Defaults to the branch of the action. 37 | - `commit_message`: The commit message to use when committing the devcard. Defaults to `Update ${filename}`. 38 | - You can use `${filename}` in the message to refer to the filename of the devcard. 39 | - `commit_filename`: The filename to commit the devcard to. Defaults to `devcard.png`. 40 | - You can also use any other filename ending in `.png`. 41 | - `committer_email`: The committer email used in commit. Defaults to `noreply@github.com`. 42 | - `committer_name`: The committer name used in commit. Defaults to `github-actions[bot]`. 43 | - `dryrun`: If set to `true`, the action will run as normal, but not actually commit the devcard 44 | 45 | ## Advanced usage 46 | 47 | This will save the devcard as PNG and commit to a separate branch named `devcard`. 48 | 49 | ```yaml 50 | jobs: 51 | devcard: 52 | runs-on: ubuntu-latest 53 | permissions: 54 | contents: write 55 | steps: 56 | - name: devcard 57 | uses: dailydotdev/action-devcard@3.2.1 58 | with: 59 | user_id: ${{ secrets.USER_ID }} 60 | commit_branch: devcard 61 | commit_filename: devcard.png 62 | commit_message: "chore: update ${filename}" 63 | ``` 64 | 65 | ## Keep up-to-date with GitHub Dependabot 66 | 67 | Since [Dependabot](https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-github-dependabot) 68 | has [native GitHub Actions support](https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#package-ecosystem), 69 | to enable it on your GitHub repo all you need to do is add the `.github/dependabot.yml` file: 70 | 71 | ```yaml 72 | version: 2 73 | updates: 74 | # Maintain dependencies for GitHub Actions 75 | - package-ecosystem: "github-actions" 76 | directory: "/" 77 | schedule: 78 | interval: "daily" 79 | ``` 80 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: '@dailydotdev/devcard' 2 | description: 'GitHub Action to download the devcard from daily.dev' 3 | author: 'Ole-Martin Bratteng' 4 | branding: 5 | icon: user-check 6 | color: gray-dark 7 | inputs: 8 | user_id: 9 | description: 'Your daily.dev user id' 10 | required: true 11 | 12 | type: 13 | description: 'Configure orientation for devcard. Must be either "default" or "wide"' 14 | default: default 15 | required: false 16 | 17 | token: 18 | description: GitHub Token used to commit the devcard 19 | default: ${{ github.token }} 20 | required: false 21 | 22 | commit_branch: 23 | description: Branch used to commit the devcard 24 | default: "" 25 | required: false 26 | 27 | commit_message: 28 | description: Commit message 29 | default: Update ${filename} 30 | required: false 31 | 32 | commit_filename: 33 | description: Filename to save devcard to 34 | default: devcard.png 35 | required: false 36 | 37 | committer_email: 38 | description: Committer email 39 | default: 41898282+github-actions[bot]@users.noreply.github.com 40 | required: false 41 | 42 | committer_name: 43 | description: Committer name 44 | default: github-actions[bot] 45 | required: false 46 | 47 | dryrun: 48 | description: 'If true, no changes will be made to the repo' 49 | default: false 50 | required: false 51 | 52 | runs: 53 | using: 'node20' 54 | main: "dist/index.js" 55 | -------------------------------------------------------------------------------- /devcard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dailydotdev/action-devcard/ac7602b631d109374554ce298f454561843fac2f/devcard.png -------------------------------------------------------------------------------- /devcard.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dailydotdev/action-devcard/ac7602b631d109374554ce298f454561843fac2f/devcard.svg -------------------------------------------------------------------------------- /dist/886.index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | exports.id = 886; 3 | exports.ids = [886]; 4 | exports.modules = { 5 | 6 | /***/ 4886: 7 | /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 8 | 9 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { 10 | /* harmony export */ toFormData: () => (/* binding */ toFormData) 11 | /* harmony export */ }); 12 | /* harmony import */ var fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(939); 13 | /* harmony import */ var formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8369); 14 | 15 | 16 | 17 | let s = 0; 18 | const S = { 19 | START_BOUNDARY: s++, 20 | HEADER_FIELD_START: s++, 21 | HEADER_FIELD: s++, 22 | HEADER_VALUE_START: s++, 23 | HEADER_VALUE: s++, 24 | HEADER_VALUE_ALMOST_DONE: s++, 25 | HEADERS_ALMOST_DONE: s++, 26 | PART_DATA_START: s++, 27 | PART_DATA: s++, 28 | END: s++ 29 | }; 30 | 31 | let f = 1; 32 | const F = { 33 | PART_BOUNDARY: f, 34 | LAST_BOUNDARY: f *= 2 35 | }; 36 | 37 | const LF = 10; 38 | const CR = 13; 39 | const SPACE = 32; 40 | const HYPHEN = 45; 41 | const COLON = 58; 42 | const A = 97; 43 | const Z = 122; 44 | 45 | const lower = c => c | 0x20; 46 | 47 | const noop = () => {}; 48 | 49 | class MultipartParser { 50 | /** 51 | * @param {string} boundary 52 | */ 53 | constructor(boundary) { 54 | this.index = 0; 55 | this.flags = 0; 56 | 57 | this.onHeaderEnd = noop; 58 | this.onHeaderField = noop; 59 | this.onHeadersEnd = noop; 60 | this.onHeaderValue = noop; 61 | this.onPartBegin = noop; 62 | this.onPartData = noop; 63 | this.onPartEnd = noop; 64 | 65 | this.boundaryChars = {}; 66 | 67 | boundary = '\r\n--' + boundary; 68 | const ui8a = new Uint8Array(boundary.length); 69 | for (let i = 0; i < boundary.length; i++) { 70 | ui8a[i] = boundary.charCodeAt(i); 71 | this.boundaryChars[ui8a[i]] = true; 72 | } 73 | 74 | this.boundary = ui8a; 75 | this.lookbehind = new Uint8Array(this.boundary.length + 8); 76 | this.state = S.START_BOUNDARY; 77 | } 78 | 79 | /** 80 | * @param {Uint8Array} data 81 | */ 82 | write(data) { 83 | let i = 0; 84 | const length_ = data.length; 85 | let previousIndex = this.index; 86 | let {lookbehind, boundary, boundaryChars, index, state, flags} = this; 87 | const boundaryLength = this.boundary.length; 88 | const boundaryEnd = boundaryLength - 1; 89 | const bufferLength = data.length; 90 | let c; 91 | let cl; 92 | 93 | const mark = name => { 94 | this[name + 'Mark'] = i; 95 | }; 96 | 97 | const clear = name => { 98 | delete this[name + 'Mark']; 99 | }; 100 | 101 | const callback = (callbackSymbol, start, end, ui8a) => { 102 | if (start === undefined || start !== end) { 103 | this[callbackSymbol](ui8a && ui8a.subarray(start, end)); 104 | } 105 | }; 106 | 107 | const dataCallback = (name, clear) => { 108 | const markSymbol = name + 'Mark'; 109 | if (!(markSymbol in this)) { 110 | return; 111 | } 112 | 113 | if (clear) { 114 | callback(name, this[markSymbol], i, data); 115 | delete this[markSymbol]; 116 | } else { 117 | callback(name, this[markSymbol], data.length, data); 118 | this[markSymbol] = 0; 119 | } 120 | }; 121 | 122 | for (i = 0; i < length_; i++) { 123 | c = data[i]; 124 | 125 | switch (state) { 126 | case S.START_BOUNDARY: 127 | if (index === boundary.length - 2) { 128 | if (c === HYPHEN) { 129 | flags |= F.LAST_BOUNDARY; 130 | } else if (c !== CR) { 131 | return; 132 | } 133 | 134 | index++; 135 | break; 136 | } else if (index - 1 === boundary.length - 2) { 137 | if (flags & F.LAST_BOUNDARY && c === HYPHEN) { 138 | state = S.END; 139 | flags = 0; 140 | } else if (!(flags & F.LAST_BOUNDARY) && c === LF) { 141 | index = 0; 142 | callback('onPartBegin'); 143 | state = S.HEADER_FIELD_START; 144 | } else { 145 | return; 146 | } 147 | 148 | break; 149 | } 150 | 151 | if (c !== boundary[index + 2]) { 152 | index = -2; 153 | } 154 | 155 | if (c === boundary[index + 2]) { 156 | index++; 157 | } 158 | 159 | break; 160 | case S.HEADER_FIELD_START: 161 | state = S.HEADER_FIELD; 162 | mark('onHeaderField'); 163 | index = 0; 164 | // falls through 165 | case S.HEADER_FIELD: 166 | if (c === CR) { 167 | clear('onHeaderField'); 168 | state = S.HEADERS_ALMOST_DONE; 169 | break; 170 | } 171 | 172 | index++; 173 | if (c === HYPHEN) { 174 | break; 175 | } 176 | 177 | if (c === COLON) { 178 | if (index === 1) { 179 | // empty header field 180 | return; 181 | } 182 | 183 | dataCallback('onHeaderField', true); 184 | state = S.HEADER_VALUE_START; 185 | break; 186 | } 187 | 188 | cl = lower(c); 189 | if (cl < A || cl > Z) { 190 | return; 191 | } 192 | 193 | break; 194 | case S.HEADER_VALUE_START: 195 | if (c === SPACE) { 196 | break; 197 | } 198 | 199 | mark('onHeaderValue'); 200 | state = S.HEADER_VALUE; 201 | // falls through 202 | case S.HEADER_VALUE: 203 | if (c === CR) { 204 | dataCallback('onHeaderValue', true); 205 | callback('onHeaderEnd'); 206 | state = S.HEADER_VALUE_ALMOST_DONE; 207 | } 208 | 209 | break; 210 | case S.HEADER_VALUE_ALMOST_DONE: 211 | if (c !== LF) { 212 | return; 213 | } 214 | 215 | state = S.HEADER_FIELD_START; 216 | break; 217 | case S.HEADERS_ALMOST_DONE: 218 | if (c !== LF) { 219 | return; 220 | } 221 | 222 | callback('onHeadersEnd'); 223 | state = S.PART_DATA_START; 224 | break; 225 | case S.PART_DATA_START: 226 | state = S.PART_DATA; 227 | mark('onPartData'); 228 | // falls through 229 | case S.PART_DATA: 230 | previousIndex = index; 231 | 232 | if (index === 0) { 233 | // boyer-moore derrived algorithm to safely skip non-boundary data 234 | i += boundaryEnd; 235 | while (i < bufferLength && !(data[i] in boundaryChars)) { 236 | i += boundaryLength; 237 | } 238 | 239 | i -= boundaryEnd; 240 | c = data[i]; 241 | } 242 | 243 | if (index < boundary.length) { 244 | if (boundary[index] === c) { 245 | if (index === 0) { 246 | dataCallback('onPartData', true); 247 | } 248 | 249 | index++; 250 | } else { 251 | index = 0; 252 | } 253 | } else if (index === boundary.length) { 254 | index++; 255 | if (c === CR) { 256 | // CR = part boundary 257 | flags |= F.PART_BOUNDARY; 258 | } else if (c === HYPHEN) { 259 | // HYPHEN = end boundary 260 | flags |= F.LAST_BOUNDARY; 261 | } else { 262 | index = 0; 263 | } 264 | } else if (index - 1 === boundary.length) { 265 | if (flags & F.PART_BOUNDARY) { 266 | index = 0; 267 | if (c === LF) { 268 | // unset the PART_BOUNDARY flag 269 | flags &= ~F.PART_BOUNDARY; 270 | callback('onPartEnd'); 271 | callback('onPartBegin'); 272 | state = S.HEADER_FIELD_START; 273 | break; 274 | } 275 | } else if (flags & F.LAST_BOUNDARY) { 276 | if (c === HYPHEN) { 277 | callback('onPartEnd'); 278 | state = S.END; 279 | flags = 0; 280 | } else { 281 | index = 0; 282 | } 283 | } else { 284 | index = 0; 285 | } 286 | } 287 | 288 | if (index > 0) { 289 | // when matching a possible boundary, keep a lookbehind reference 290 | // in case it turns out to be a false lead 291 | lookbehind[index - 1] = c; 292 | } else if (previousIndex > 0) { 293 | // if our boundary turned out to be rubbish, the captured lookbehind 294 | // belongs to partData 295 | const _lookbehind = new Uint8Array(lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength); 296 | callback('onPartData', 0, previousIndex, _lookbehind); 297 | previousIndex = 0; 298 | mark('onPartData'); 299 | 300 | // reconsider the current character even so it interrupted the sequence 301 | // it could be the beginning of a new sequence 302 | i--; 303 | } 304 | 305 | break; 306 | case S.END: 307 | break; 308 | default: 309 | throw new Error(`Unexpected state entered: ${state}`); 310 | } 311 | } 312 | 313 | dataCallback('onHeaderField'); 314 | dataCallback('onHeaderValue'); 315 | dataCallback('onPartData'); 316 | 317 | // Update properties for the next call 318 | this.index = index; 319 | this.state = state; 320 | this.flags = flags; 321 | } 322 | 323 | end() { 324 | if ((this.state === S.HEADER_FIELD_START && this.index === 0) || 325 | (this.state === S.PART_DATA && this.index === this.boundary.length)) { 326 | this.onPartEnd(); 327 | } else if (this.state !== S.END) { 328 | throw new Error('MultipartParser.end(): stream ended unexpectedly'); 329 | } 330 | } 331 | } 332 | 333 | function _fileName(headerValue) { 334 | // matches either a quoted-string or a token (RFC 2616 section 19.5.1) 335 | const m = headerValue.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i); 336 | if (!m) { 337 | return; 338 | } 339 | 340 | const match = m[2] || m[3] || ''; 341 | let filename = match.slice(match.lastIndexOf('\\') + 1); 342 | filename = filename.replace(/%22/g, '"'); 343 | filename = filename.replace(/&#(\d{4});/g, (m, code) => { 344 | return String.fromCharCode(code); 345 | }); 346 | return filename; 347 | } 348 | 349 | async function toFormData(Body, ct) { 350 | if (!/multipart/i.test(ct)) { 351 | throw new TypeError('Failed to fetch'); 352 | } 353 | 354 | const m = ct.match(/boundary=(?:"([^"]+)"|([^;]+))/i); 355 | 356 | if (!m) { 357 | throw new TypeError('no or bad content-type header, no multipart boundary'); 358 | } 359 | 360 | const parser = new MultipartParser(m[1] || m[2]); 361 | 362 | let headerField; 363 | let headerValue; 364 | let entryValue; 365 | let entryName; 366 | let contentType; 367 | let filename; 368 | const entryChunks = []; 369 | const formData = new formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__/* .FormData */ .fS(); 370 | 371 | const onPartData = ui8a => { 372 | entryValue += decoder.decode(ui8a, {stream: true}); 373 | }; 374 | 375 | const appendToFile = ui8a => { 376 | entryChunks.push(ui8a); 377 | }; 378 | 379 | const appendFileToFormData = () => { 380 | const file = new fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__/* .File */ .ZH(entryChunks, filename, {type: contentType}); 381 | formData.append(entryName, file); 382 | }; 383 | 384 | const appendEntryToFormData = () => { 385 | formData.append(entryName, entryValue); 386 | }; 387 | 388 | const decoder = new TextDecoder('utf-8'); 389 | decoder.decode(); 390 | 391 | parser.onPartBegin = function () { 392 | parser.onPartData = onPartData; 393 | parser.onPartEnd = appendEntryToFormData; 394 | 395 | headerField = ''; 396 | headerValue = ''; 397 | entryValue = ''; 398 | entryName = ''; 399 | contentType = ''; 400 | filename = null; 401 | entryChunks.length = 0; 402 | }; 403 | 404 | parser.onHeaderField = function (ui8a) { 405 | headerField += decoder.decode(ui8a, {stream: true}); 406 | }; 407 | 408 | parser.onHeaderValue = function (ui8a) { 409 | headerValue += decoder.decode(ui8a, {stream: true}); 410 | }; 411 | 412 | parser.onHeaderEnd = function () { 413 | headerValue += decoder.decode(); 414 | headerField = headerField.toLowerCase(); 415 | 416 | if (headerField === 'content-disposition') { 417 | // matches either a quoted-string or a token (RFC 2616 section 19.5.1) 418 | const m = headerValue.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i); 419 | 420 | if (m) { 421 | entryName = m[2] || m[3] || ''; 422 | } 423 | 424 | filename = _fileName(headerValue); 425 | 426 | if (filename) { 427 | parser.onPartData = appendToFile; 428 | parser.onPartEnd = appendFileToFormData; 429 | } 430 | } else if (headerField === 'content-type') { 431 | contentType = headerValue; 432 | } 433 | 434 | headerValue = ''; 435 | headerField = ''; 436 | }; 437 | 438 | for await (const chunk of Body) { 439 | parser.write(chunk); 440 | } 441 | 442 | parser.end(); 443 | 444 | return formData; 445 | } 446 | 447 | 448 | /***/ }) 449 | 450 | }; 451 | ; -------------------------------------------------------------------------------- /dist/license.txt: -------------------------------------------------------------------------------- 1 | node-fetch 2 | MIT 3 | The MIT License (MIT) 4 | 5 | Copyright (c) 2016 - 2020 Node Fetch Team 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "action-devcard", 3 | "version": "3.2.1", 4 | "description": "GitHub Action to download the devcard from daily.dev", 5 | "private": true, 6 | "author": { 7 | "name": "Ole-Martin Bratteng", 8 | "email": "ole-martin@bratteng.com" 9 | }, 10 | "contributors": [ 11 | { 12 | "name": "Ole-Martin Bratteng", 13 | "email": "ole-martin@bratteng.com" 14 | }, 15 | { 16 | "name": "Milan Freml", 17 | "email": "kopancek@gmail.com" 18 | } 19 | ], 20 | "scripts": { 21 | "lint": "eslint 'src/**/*.ts' --cache", 22 | "build": "ncc build --out dist --target es2023 --minify --license license.txt src/index.ts" 23 | }, 24 | "main": "src/index.ts", 25 | "repository": "github:dailydotdev/action-devcard", 26 | "bugs": "https://github.com/dailydotdev/action-devcard/issues", 27 | "license": "BSD-3-Clause", 28 | "dependencies": { 29 | "@actions/core": "^1.11.1", 30 | "@actions/github": "^6.0.0", 31 | "node-fetch": "^3.3.2", 32 | "simple-git": "^3.27.0" 33 | }, 34 | "devDependencies": { 35 | "@octokit/graphql": "^8.2.1", 36 | "@types/jsdom": "21.x", 37 | "@types/node": "22.x", 38 | "@typescript-eslint/eslint-plugin": "^8.25.0", 39 | "@typescript-eslint/parser": "^8.22.0", 40 | "@vercel/ncc": "0.38.3", 41 | "dotenv": "^16.4.7", 42 | "eslint": "^8.57.1", 43 | "eslint-config-prettier": "^10.0.1", 44 | "eslint-plugin-prettier": "^5.2.3", 45 | "prettier": "^3.5.2", 46 | "typescript": "^5.7.3" 47 | }, 48 | "packageManager": "pnpm@9.12.3" 49 | } 50 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@actions/core': 12 | specifier: ^1.11.1 13 | version: 1.11.1 14 | '@actions/github': 15 | specifier: ^6.0.0 16 | version: 6.0.0 17 | node-fetch: 18 | specifier: ^3.3.2 19 | version: 3.3.2 20 | simple-git: 21 | specifier: ^3.27.0 22 | version: 3.27.0 23 | devDependencies: 24 | '@octokit/graphql': 25 | specifier: ^8.2.1 26 | version: 8.2.1 27 | '@types/jsdom': 28 | specifier: 21.x 29 | version: 21.1.7 30 | '@types/node': 31 | specifier: 22.x 32 | version: 22.13.8 33 | '@typescript-eslint/eslint-plugin': 34 | specifier: ^8.25.0 35 | version: 8.25.0(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3) 36 | '@typescript-eslint/parser': 37 | specifier: ^8.22.0 38 | version: 8.22.0(eslint@8.57.1)(typescript@5.7.3) 39 | '@vercel/ncc': 40 | specifier: 0.38.3 41 | version: 0.38.3 42 | dotenv: 43 | specifier: ^16.4.7 44 | version: 16.4.7 45 | eslint: 46 | specifier: ^8.57.1 47 | version: 8.57.1 48 | eslint-config-prettier: 49 | specifier: ^10.0.1 50 | version: 10.0.1(eslint@8.57.1) 51 | eslint-plugin-prettier: 52 | specifier: ^5.2.3 53 | version: 5.2.3(eslint-config-prettier@10.0.1(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.2) 54 | prettier: 55 | specifier: ^3.5.2 56 | version: 3.5.2 57 | typescript: 58 | specifier: ^5.7.3 59 | version: 5.7.3 60 | 61 | packages: 62 | 63 | '@actions/core@1.11.1': 64 | resolution: {integrity: sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==} 65 | 66 | '@actions/exec@1.1.1': 67 | resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==} 68 | 69 | '@actions/github@6.0.0': 70 | resolution: {integrity: sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==} 71 | 72 | '@actions/http-client@2.2.3': 73 | resolution: {integrity: sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==} 74 | 75 | '@actions/io@1.1.3': 76 | resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==} 77 | 78 | '@eslint-community/eslint-utils@4.4.0': 79 | resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} 80 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 81 | peerDependencies: 82 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 83 | 84 | '@eslint-community/eslint-utils@4.4.1': 85 | resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} 86 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 87 | peerDependencies: 88 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 89 | 90 | '@eslint-community/regexpp@4.11.1': 91 | resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} 92 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 93 | 94 | '@eslint-community/regexpp@4.12.1': 95 | resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} 96 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 97 | 98 | '@eslint/eslintrc@2.1.4': 99 | resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} 100 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 101 | 102 | '@eslint/js@8.57.1': 103 | resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} 104 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 105 | 106 | '@fastify/busboy@2.1.1': 107 | resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} 108 | engines: {node: '>=14'} 109 | 110 | '@humanwhocodes/config-array@0.13.0': 111 | resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} 112 | engines: {node: '>=10.10.0'} 113 | deprecated: Use @eslint/config-array instead 114 | 115 | '@humanwhocodes/module-importer@1.0.1': 116 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} 117 | engines: {node: '>=12.22'} 118 | 119 | '@humanwhocodes/object-schema@2.0.3': 120 | resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} 121 | deprecated: Use @eslint/object-schema instead 122 | 123 | '@kwsites/file-exists@1.1.1': 124 | resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} 125 | 126 | '@kwsites/promise-deferred@1.1.1': 127 | resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} 128 | 129 | '@nodelib/fs.scandir@2.1.5': 130 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 131 | engines: {node: '>= 8'} 132 | 133 | '@nodelib/fs.stat@2.0.5': 134 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 135 | engines: {node: '>= 8'} 136 | 137 | '@nodelib/fs.walk@1.2.8': 138 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 139 | engines: {node: '>= 8'} 140 | 141 | '@octokit/auth-token@4.0.0': 142 | resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} 143 | engines: {node: '>= 18'} 144 | 145 | '@octokit/core@5.2.0': 146 | resolution: {integrity: sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==} 147 | engines: {node: '>= 18'} 148 | 149 | '@octokit/endpoint@10.1.3': 150 | resolution: {integrity: sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==} 151 | engines: {node: '>= 18'} 152 | 153 | '@octokit/endpoint@9.0.6': 154 | resolution: {integrity: sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==} 155 | engines: {node: '>= 18'} 156 | 157 | '@octokit/graphql@7.1.1': 158 | resolution: {integrity: sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==} 159 | engines: {node: '>= 18'} 160 | 161 | '@octokit/graphql@8.2.1': 162 | resolution: {integrity: sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==} 163 | engines: {node: '>= 18'} 164 | 165 | '@octokit/openapi-types@20.0.0': 166 | resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==} 167 | 168 | '@octokit/openapi-types@23.0.1': 169 | resolution: {integrity: sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==} 170 | 171 | '@octokit/plugin-paginate-rest@9.2.1': 172 | resolution: {integrity: sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==} 173 | engines: {node: '>= 18'} 174 | peerDependencies: 175 | '@octokit/core': '5' 176 | 177 | '@octokit/plugin-rest-endpoint-methods@10.4.1': 178 | resolution: {integrity: sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==} 179 | engines: {node: '>= 18'} 180 | peerDependencies: 181 | '@octokit/core': '5' 182 | 183 | '@octokit/request-error@5.1.0': 184 | resolution: {integrity: sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==} 185 | engines: {node: '>= 18'} 186 | 187 | '@octokit/request-error@5.1.1': 188 | resolution: {integrity: sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==} 189 | engines: {node: '>= 18'} 190 | 191 | '@octokit/request-error@6.1.7': 192 | resolution: {integrity: sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==} 193 | engines: {node: '>= 18'} 194 | 195 | '@octokit/request@8.4.1': 196 | resolution: {integrity: sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==} 197 | engines: {node: '>= 18'} 198 | 199 | '@octokit/request@9.2.2': 200 | resolution: {integrity: sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==} 201 | engines: {node: '>= 18'} 202 | 203 | '@octokit/types@12.6.0': 204 | resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==} 205 | 206 | '@octokit/types@13.8.0': 207 | resolution: {integrity: sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==} 208 | 209 | '@pkgr/core@0.1.1': 210 | resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} 211 | engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} 212 | 213 | '@types/jsdom@21.1.7': 214 | resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==} 215 | 216 | '@types/node@22.13.8': 217 | resolution: {integrity: sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ==} 218 | 219 | '@types/tough-cookie@4.0.5': 220 | resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} 221 | 222 | '@typescript-eslint/eslint-plugin@8.25.0': 223 | resolution: {integrity: sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA==} 224 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 225 | peerDependencies: 226 | '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 227 | eslint: ^8.57.0 || ^9.0.0 228 | typescript: '>=4.8.4 <5.8.0' 229 | 230 | '@typescript-eslint/parser@8.22.0': 231 | resolution: {integrity: sha512-MqtmbdNEdoNxTPzpWiWnqNac54h8JDAmkWtJExBVVnSrSmi9z+sZUt0LfKqk9rjqmKOIeRhO4fHHJ1nQIjduIQ==} 232 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 233 | peerDependencies: 234 | eslint: ^8.57.0 || ^9.0.0 235 | typescript: '>=4.8.4 <5.8.0' 236 | 237 | '@typescript-eslint/scope-manager@8.22.0': 238 | resolution: {integrity: sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==} 239 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 240 | 241 | '@typescript-eslint/scope-manager@8.25.0': 242 | resolution: {integrity: sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg==} 243 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 244 | 245 | '@typescript-eslint/type-utils@8.25.0': 246 | resolution: {integrity: sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g==} 247 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 248 | peerDependencies: 249 | eslint: ^8.57.0 || ^9.0.0 250 | typescript: '>=4.8.4 <5.8.0' 251 | 252 | '@typescript-eslint/types@8.22.0': 253 | resolution: {integrity: sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==} 254 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 255 | 256 | '@typescript-eslint/types@8.25.0': 257 | resolution: {integrity: sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw==} 258 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 259 | 260 | '@typescript-eslint/typescript-estree@8.22.0': 261 | resolution: {integrity: sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==} 262 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 263 | peerDependencies: 264 | typescript: '>=4.8.4 <5.8.0' 265 | 266 | '@typescript-eslint/typescript-estree@8.25.0': 267 | resolution: {integrity: sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==} 268 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 269 | peerDependencies: 270 | typescript: '>=4.8.4 <5.8.0' 271 | 272 | '@typescript-eslint/utils@8.25.0': 273 | resolution: {integrity: sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA==} 274 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 275 | peerDependencies: 276 | eslint: ^8.57.0 || ^9.0.0 277 | typescript: '>=4.8.4 <5.8.0' 278 | 279 | '@typescript-eslint/visitor-keys@8.22.0': 280 | resolution: {integrity: sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==} 281 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 282 | 283 | '@typescript-eslint/visitor-keys@8.25.0': 284 | resolution: {integrity: sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ==} 285 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 286 | 287 | '@ungap/structured-clone@1.2.0': 288 | resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} 289 | 290 | '@vercel/ncc@0.38.3': 291 | resolution: {integrity: sha512-rnK6hJBS6mwc+Bkab+PGPs9OiS0i/3kdTO+CkI8V0/VrW3vmz7O2Pxjw/owOlmo6PKEIxRSeZKv/kuL9itnpYA==} 292 | hasBin: true 293 | 294 | acorn-jsx@5.3.2: 295 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 296 | peerDependencies: 297 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 298 | 299 | acorn@8.13.0: 300 | resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} 301 | engines: {node: '>=0.4.0'} 302 | hasBin: true 303 | 304 | ajv@6.12.6: 305 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 306 | 307 | ansi-regex@5.0.1: 308 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 309 | engines: {node: '>=8'} 310 | 311 | ansi-styles@4.3.0: 312 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 313 | engines: {node: '>=8'} 314 | 315 | argparse@2.0.1: 316 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 317 | 318 | balanced-match@1.0.2: 319 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 320 | 321 | before-after-hook@2.2.3: 322 | resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} 323 | 324 | brace-expansion@1.1.11: 325 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 326 | 327 | brace-expansion@2.0.1: 328 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 329 | 330 | braces@3.0.3: 331 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 332 | engines: {node: '>=8'} 333 | 334 | callsites@3.1.0: 335 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 336 | engines: {node: '>=6'} 337 | 338 | chalk@4.1.2: 339 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 340 | engines: {node: '>=10'} 341 | 342 | color-convert@2.0.1: 343 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 344 | engines: {node: '>=7.0.0'} 345 | 346 | color-name@1.1.4: 347 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 348 | 349 | concat-map@0.0.1: 350 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 351 | 352 | cross-spawn@7.0.3: 353 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 354 | engines: {node: '>= 8'} 355 | 356 | data-uri-to-buffer@4.0.1: 357 | resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} 358 | engines: {node: '>= 12'} 359 | 360 | debug@4.3.7: 361 | resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} 362 | engines: {node: '>=6.0'} 363 | peerDependencies: 364 | supports-color: '*' 365 | peerDependenciesMeta: 366 | supports-color: 367 | optional: true 368 | 369 | debug@4.4.0: 370 | resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} 371 | engines: {node: '>=6.0'} 372 | peerDependencies: 373 | supports-color: '*' 374 | peerDependenciesMeta: 375 | supports-color: 376 | optional: true 377 | 378 | deep-is@0.1.4: 379 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 380 | 381 | deprecation@2.3.1: 382 | resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} 383 | 384 | doctrine@3.0.0: 385 | resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} 386 | engines: {node: '>=6.0.0'} 387 | 388 | dotenv@16.4.7: 389 | resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} 390 | engines: {node: '>=12'} 391 | 392 | entities@4.5.0: 393 | resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 394 | engines: {node: '>=0.12'} 395 | 396 | escape-string-regexp@4.0.0: 397 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 398 | engines: {node: '>=10'} 399 | 400 | eslint-config-prettier@10.0.1: 401 | resolution: {integrity: sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==} 402 | hasBin: true 403 | peerDependencies: 404 | eslint: '>=7.0.0' 405 | 406 | eslint-plugin-prettier@5.2.3: 407 | resolution: {integrity: sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==} 408 | engines: {node: ^14.18.0 || >=16.0.0} 409 | peerDependencies: 410 | '@types/eslint': '>=8.0.0' 411 | eslint: '>=8.0.0' 412 | eslint-config-prettier: '*' 413 | prettier: '>=3.0.0' 414 | peerDependenciesMeta: 415 | '@types/eslint': 416 | optional: true 417 | eslint-config-prettier: 418 | optional: true 419 | 420 | eslint-scope@7.2.2: 421 | resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} 422 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 423 | 424 | eslint-visitor-keys@3.4.3: 425 | resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} 426 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 427 | 428 | eslint-visitor-keys@4.2.0: 429 | resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} 430 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 431 | 432 | eslint@8.57.1: 433 | resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} 434 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 435 | deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. 436 | hasBin: true 437 | 438 | espree@9.6.1: 439 | resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} 440 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 441 | 442 | esquery@1.6.0: 443 | resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} 444 | engines: {node: '>=0.10'} 445 | 446 | esrecurse@4.3.0: 447 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 448 | engines: {node: '>=4.0'} 449 | 450 | estraverse@5.3.0: 451 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 452 | engines: {node: '>=4.0'} 453 | 454 | esutils@2.0.3: 455 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 456 | engines: {node: '>=0.10.0'} 457 | 458 | fast-content-type-parse@2.0.1: 459 | resolution: {integrity: sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==} 460 | 461 | fast-deep-equal@3.1.3: 462 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 463 | 464 | fast-diff@1.3.0: 465 | resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} 466 | 467 | fast-glob@3.3.3: 468 | resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} 469 | engines: {node: '>=8.6.0'} 470 | 471 | fast-json-stable-stringify@2.1.0: 472 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 473 | 474 | fast-levenshtein@2.0.6: 475 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 476 | 477 | fastq@1.17.1: 478 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} 479 | 480 | fetch-blob@3.2.0: 481 | resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} 482 | engines: {node: ^12.20 || >= 14.13} 483 | 484 | file-entry-cache@6.0.1: 485 | resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} 486 | engines: {node: ^10.12.0 || >=12.0.0} 487 | 488 | fill-range@7.1.1: 489 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 490 | engines: {node: '>=8'} 491 | 492 | find-up@5.0.0: 493 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 494 | engines: {node: '>=10'} 495 | 496 | flat-cache@3.2.0: 497 | resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} 498 | engines: {node: ^10.12.0 || >=12.0.0} 499 | 500 | flatted@3.3.1: 501 | resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} 502 | 503 | formdata-polyfill@4.0.10: 504 | resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} 505 | engines: {node: '>=12.20.0'} 506 | 507 | fs.realpath@1.0.0: 508 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 509 | 510 | glob-parent@5.1.2: 511 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 512 | engines: {node: '>= 6'} 513 | 514 | glob-parent@6.0.2: 515 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 516 | engines: {node: '>=10.13.0'} 517 | 518 | glob@7.2.3: 519 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 520 | deprecated: Glob versions prior to v9 are no longer supported 521 | 522 | globals@13.24.0: 523 | resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} 524 | engines: {node: '>=8'} 525 | 526 | graphemer@1.4.0: 527 | resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} 528 | 529 | has-flag@4.0.0: 530 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 531 | engines: {node: '>=8'} 532 | 533 | ignore@5.3.2: 534 | resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 535 | engines: {node: '>= 4'} 536 | 537 | import-fresh@3.3.0: 538 | resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} 539 | engines: {node: '>=6'} 540 | 541 | imurmurhash@0.1.4: 542 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 543 | engines: {node: '>=0.8.19'} 544 | 545 | inflight@1.0.6: 546 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 547 | deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. 548 | 549 | inherits@2.0.4: 550 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 551 | 552 | is-extglob@2.1.1: 553 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 554 | engines: {node: '>=0.10.0'} 555 | 556 | is-glob@4.0.3: 557 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 558 | engines: {node: '>=0.10.0'} 559 | 560 | is-number@7.0.0: 561 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 562 | engines: {node: '>=0.12.0'} 563 | 564 | is-path-inside@3.0.3: 565 | resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} 566 | engines: {node: '>=8'} 567 | 568 | isexe@2.0.0: 569 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 570 | 571 | js-yaml@4.1.0: 572 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 573 | hasBin: true 574 | 575 | json-buffer@3.0.1: 576 | resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} 577 | 578 | json-schema-traverse@0.4.1: 579 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 580 | 581 | json-stable-stringify-without-jsonify@1.0.1: 582 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 583 | 584 | keyv@4.5.4: 585 | resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} 586 | 587 | levn@0.4.1: 588 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 589 | engines: {node: '>= 0.8.0'} 590 | 591 | locate-path@6.0.0: 592 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 593 | engines: {node: '>=10'} 594 | 595 | lodash.merge@4.6.2: 596 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 597 | 598 | merge2@1.4.1: 599 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 600 | engines: {node: '>= 8'} 601 | 602 | micromatch@4.0.8: 603 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 604 | engines: {node: '>=8.6'} 605 | 606 | minimatch@3.1.2: 607 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 608 | 609 | minimatch@9.0.5: 610 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 611 | engines: {node: '>=16 || 14 >=14.17'} 612 | 613 | ms@2.1.3: 614 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 615 | 616 | natural-compare@1.4.0: 617 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 618 | 619 | node-domexception@1.0.0: 620 | resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} 621 | engines: {node: '>=10.5.0'} 622 | 623 | node-fetch@3.3.2: 624 | resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} 625 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 626 | 627 | once@1.4.0: 628 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 629 | 630 | optionator@0.9.4: 631 | resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} 632 | engines: {node: '>= 0.8.0'} 633 | 634 | p-limit@3.1.0: 635 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 636 | engines: {node: '>=10'} 637 | 638 | p-locate@5.0.0: 639 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 640 | engines: {node: '>=10'} 641 | 642 | parent-module@1.0.1: 643 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 644 | engines: {node: '>=6'} 645 | 646 | parse5@7.2.0: 647 | resolution: {integrity: sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==} 648 | 649 | path-exists@4.0.0: 650 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 651 | engines: {node: '>=8'} 652 | 653 | path-is-absolute@1.0.1: 654 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 655 | engines: {node: '>=0.10.0'} 656 | 657 | path-key@3.1.1: 658 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 659 | engines: {node: '>=8'} 660 | 661 | picomatch@2.3.1: 662 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 663 | engines: {node: '>=8.6'} 664 | 665 | prelude-ls@1.2.1: 666 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 667 | engines: {node: '>= 0.8.0'} 668 | 669 | prettier-linter-helpers@1.0.0: 670 | resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} 671 | engines: {node: '>=6.0.0'} 672 | 673 | prettier@3.5.2: 674 | resolution: {integrity: sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==} 675 | engines: {node: '>=14'} 676 | hasBin: true 677 | 678 | punycode@2.3.1: 679 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 680 | engines: {node: '>=6'} 681 | 682 | queue-microtask@1.2.3: 683 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 684 | 685 | resolve-from@4.0.0: 686 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 687 | engines: {node: '>=4'} 688 | 689 | reusify@1.0.4: 690 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 691 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 692 | 693 | rimraf@3.0.2: 694 | resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} 695 | deprecated: Rimraf versions prior to v4 are no longer supported 696 | hasBin: true 697 | 698 | run-parallel@1.2.0: 699 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 700 | 701 | semver@7.7.0: 702 | resolution: {integrity: sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==} 703 | engines: {node: '>=10'} 704 | hasBin: true 705 | 706 | semver@7.7.1: 707 | resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} 708 | engines: {node: '>=10'} 709 | hasBin: true 710 | 711 | shebang-command@2.0.0: 712 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 713 | engines: {node: '>=8'} 714 | 715 | shebang-regex@3.0.0: 716 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 717 | engines: {node: '>=8'} 718 | 719 | simple-git@3.27.0: 720 | resolution: {integrity: sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==} 721 | 722 | strip-ansi@6.0.1: 723 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 724 | engines: {node: '>=8'} 725 | 726 | strip-json-comments@3.1.1: 727 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 728 | engines: {node: '>=8'} 729 | 730 | supports-color@7.2.0: 731 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 732 | engines: {node: '>=8'} 733 | 734 | synckit@0.9.2: 735 | resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} 736 | engines: {node: ^14.18.0 || >=16.0.0} 737 | 738 | text-table@0.2.0: 739 | resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} 740 | 741 | to-regex-range@5.0.1: 742 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 743 | engines: {node: '>=8.0'} 744 | 745 | ts-api-utils@2.0.1: 746 | resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} 747 | engines: {node: '>=18.12'} 748 | peerDependencies: 749 | typescript: '>=4.8.4' 750 | 751 | tslib@2.8.1: 752 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 753 | 754 | tunnel@0.0.6: 755 | resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} 756 | engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} 757 | 758 | type-check@0.4.0: 759 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 760 | engines: {node: '>= 0.8.0'} 761 | 762 | type-fest@0.20.2: 763 | resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} 764 | engines: {node: '>=10'} 765 | 766 | typescript@5.7.3: 767 | resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} 768 | engines: {node: '>=14.17'} 769 | hasBin: true 770 | 771 | undici-types@6.20.0: 772 | resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} 773 | 774 | undici@5.28.4: 775 | resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} 776 | engines: {node: '>=14.0'} 777 | 778 | universal-user-agent@6.0.1: 779 | resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} 780 | 781 | universal-user-agent@7.0.2: 782 | resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==} 783 | 784 | uri-js@4.4.1: 785 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 786 | 787 | web-streams-polyfill@3.3.3: 788 | resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} 789 | engines: {node: '>= 8'} 790 | 791 | which@2.0.2: 792 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 793 | engines: {node: '>= 8'} 794 | hasBin: true 795 | 796 | word-wrap@1.2.5: 797 | resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} 798 | engines: {node: '>=0.10.0'} 799 | 800 | wrappy@1.0.2: 801 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 802 | 803 | yocto-queue@0.1.0: 804 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 805 | engines: {node: '>=10'} 806 | 807 | snapshots: 808 | 809 | '@actions/core@1.11.1': 810 | dependencies: 811 | '@actions/exec': 1.1.1 812 | '@actions/http-client': 2.2.3 813 | 814 | '@actions/exec@1.1.1': 815 | dependencies: 816 | '@actions/io': 1.1.3 817 | 818 | '@actions/github@6.0.0': 819 | dependencies: 820 | '@actions/http-client': 2.2.3 821 | '@octokit/core': 5.2.0 822 | '@octokit/plugin-paginate-rest': 9.2.1(@octokit/core@5.2.0) 823 | '@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.2.0) 824 | 825 | '@actions/http-client@2.2.3': 826 | dependencies: 827 | tunnel: 0.0.6 828 | undici: 5.28.4 829 | 830 | '@actions/io@1.1.3': {} 831 | 832 | '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': 833 | dependencies: 834 | eslint: 8.57.1 835 | eslint-visitor-keys: 3.4.3 836 | 837 | '@eslint-community/eslint-utils@4.4.1(eslint@8.57.1)': 838 | dependencies: 839 | eslint: 8.57.1 840 | eslint-visitor-keys: 3.4.3 841 | 842 | '@eslint-community/regexpp@4.11.1': {} 843 | 844 | '@eslint-community/regexpp@4.12.1': {} 845 | 846 | '@eslint/eslintrc@2.1.4': 847 | dependencies: 848 | ajv: 6.12.6 849 | debug: 4.3.7 850 | espree: 9.6.1 851 | globals: 13.24.0 852 | ignore: 5.3.2 853 | import-fresh: 3.3.0 854 | js-yaml: 4.1.0 855 | minimatch: 3.1.2 856 | strip-json-comments: 3.1.1 857 | transitivePeerDependencies: 858 | - supports-color 859 | 860 | '@eslint/js@8.57.1': {} 861 | 862 | '@fastify/busboy@2.1.1': {} 863 | 864 | '@humanwhocodes/config-array@0.13.0': 865 | dependencies: 866 | '@humanwhocodes/object-schema': 2.0.3 867 | debug: 4.3.7 868 | minimatch: 3.1.2 869 | transitivePeerDependencies: 870 | - supports-color 871 | 872 | '@humanwhocodes/module-importer@1.0.1': {} 873 | 874 | '@humanwhocodes/object-schema@2.0.3': {} 875 | 876 | '@kwsites/file-exists@1.1.1': 877 | dependencies: 878 | debug: 4.3.7 879 | transitivePeerDependencies: 880 | - supports-color 881 | 882 | '@kwsites/promise-deferred@1.1.1': {} 883 | 884 | '@nodelib/fs.scandir@2.1.5': 885 | dependencies: 886 | '@nodelib/fs.stat': 2.0.5 887 | run-parallel: 1.2.0 888 | 889 | '@nodelib/fs.stat@2.0.5': {} 890 | 891 | '@nodelib/fs.walk@1.2.8': 892 | dependencies: 893 | '@nodelib/fs.scandir': 2.1.5 894 | fastq: 1.17.1 895 | 896 | '@octokit/auth-token@4.0.0': {} 897 | 898 | '@octokit/core@5.2.0': 899 | dependencies: 900 | '@octokit/auth-token': 4.0.0 901 | '@octokit/graphql': 7.1.1 902 | '@octokit/request': 8.4.1 903 | '@octokit/request-error': 5.1.0 904 | '@octokit/types': 13.8.0 905 | before-after-hook: 2.2.3 906 | universal-user-agent: 6.0.1 907 | 908 | '@octokit/endpoint@10.1.3': 909 | dependencies: 910 | '@octokit/types': 13.8.0 911 | universal-user-agent: 7.0.2 912 | 913 | '@octokit/endpoint@9.0.6': 914 | dependencies: 915 | '@octokit/types': 13.8.0 916 | universal-user-agent: 6.0.1 917 | 918 | '@octokit/graphql@7.1.1': 919 | dependencies: 920 | '@octokit/request': 8.4.1 921 | '@octokit/types': 13.8.0 922 | universal-user-agent: 6.0.1 923 | 924 | '@octokit/graphql@8.2.1': 925 | dependencies: 926 | '@octokit/request': 9.2.2 927 | '@octokit/types': 13.8.0 928 | universal-user-agent: 7.0.2 929 | 930 | '@octokit/openapi-types@20.0.0': {} 931 | 932 | '@octokit/openapi-types@23.0.1': {} 933 | 934 | '@octokit/plugin-paginate-rest@9.2.1(@octokit/core@5.2.0)': 935 | dependencies: 936 | '@octokit/core': 5.2.0 937 | '@octokit/types': 12.6.0 938 | 939 | '@octokit/plugin-rest-endpoint-methods@10.4.1(@octokit/core@5.2.0)': 940 | dependencies: 941 | '@octokit/core': 5.2.0 942 | '@octokit/types': 12.6.0 943 | 944 | '@octokit/request-error@5.1.0': 945 | dependencies: 946 | '@octokit/types': 13.8.0 947 | deprecation: 2.3.1 948 | once: 1.4.0 949 | 950 | '@octokit/request-error@5.1.1': 951 | dependencies: 952 | '@octokit/types': 13.8.0 953 | deprecation: 2.3.1 954 | once: 1.4.0 955 | 956 | '@octokit/request-error@6.1.7': 957 | dependencies: 958 | '@octokit/types': 13.8.0 959 | 960 | '@octokit/request@8.4.1': 961 | dependencies: 962 | '@octokit/endpoint': 9.0.6 963 | '@octokit/request-error': 5.1.1 964 | '@octokit/types': 13.8.0 965 | universal-user-agent: 6.0.1 966 | 967 | '@octokit/request@9.2.2': 968 | dependencies: 969 | '@octokit/endpoint': 10.1.3 970 | '@octokit/request-error': 6.1.7 971 | '@octokit/types': 13.8.0 972 | fast-content-type-parse: 2.0.1 973 | universal-user-agent: 7.0.2 974 | 975 | '@octokit/types@12.6.0': 976 | dependencies: 977 | '@octokit/openapi-types': 20.0.0 978 | 979 | '@octokit/types@13.8.0': 980 | dependencies: 981 | '@octokit/openapi-types': 23.0.1 982 | 983 | '@pkgr/core@0.1.1': {} 984 | 985 | '@types/jsdom@21.1.7': 986 | dependencies: 987 | '@types/node': 22.13.8 988 | '@types/tough-cookie': 4.0.5 989 | parse5: 7.2.0 990 | 991 | '@types/node@22.13.8': 992 | dependencies: 993 | undici-types: 6.20.0 994 | 995 | '@types/tough-cookie@4.0.5': {} 996 | 997 | '@typescript-eslint/eslint-plugin@8.25.0(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)': 998 | dependencies: 999 | '@eslint-community/regexpp': 4.12.1 1000 | '@typescript-eslint/parser': 8.22.0(eslint@8.57.1)(typescript@5.7.3) 1001 | '@typescript-eslint/scope-manager': 8.25.0 1002 | '@typescript-eslint/type-utils': 8.25.0(eslint@8.57.1)(typescript@5.7.3) 1003 | '@typescript-eslint/utils': 8.25.0(eslint@8.57.1)(typescript@5.7.3) 1004 | '@typescript-eslint/visitor-keys': 8.25.0 1005 | eslint: 8.57.1 1006 | graphemer: 1.4.0 1007 | ignore: 5.3.2 1008 | natural-compare: 1.4.0 1009 | ts-api-utils: 2.0.1(typescript@5.7.3) 1010 | typescript: 5.7.3 1011 | transitivePeerDependencies: 1012 | - supports-color 1013 | 1014 | '@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.7.3)': 1015 | dependencies: 1016 | '@typescript-eslint/scope-manager': 8.22.0 1017 | '@typescript-eslint/types': 8.22.0 1018 | '@typescript-eslint/typescript-estree': 8.22.0(typescript@5.7.3) 1019 | '@typescript-eslint/visitor-keys': 8.22.0 1020 | debug: 4.4.0 1021 | eslint: 8.57.1 1022 | typescript: 5.7.3 1023 | transitivePeerDependencies: 1024 | - supports-color 1025 | 1026 | '@typescript-eslint/scope-manager@8.22.0': 1027 | dependencies: 1028 | '@typescript-eslint/types': 8.22.0 1029 | '@typescript-eslint/visitor-keys': 8.22.0 1030 | 1031 | '@typescript-eslint/scope-manager@8.25.0': 1032 | dependencies: 1033 | '@typescript-eslint/types': 8.25.0 1034 | '@typescript-eslint/visitor-keys': 8.25.0 1035 | 1036 | '@typescript-eslint/type-utils@8.25.0(eslint@8.57.1)(typescript@5.7.3)': 1037 | dependencies: 1038 | '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.7.3) 1039 | '@typescript-eslint/utils': 8.25.0(eslint@8.57.1)(typescript@5.7.3) 1040 | debug: 4.4.0 1041 | eslint: 8.57.1 1042 | ts-api-utils: 2.0.1(typescript@5.7.3) 1043 | typescript: 5.7.3 1044 | transitivePeerDependencies: 1045 | - supports-color 1046 | 1047 | '@typescript-eslint/types@8.22.0': {} 1048 | 1049 | '@typescript-eslint/types@8.25.0': {} 1050 | 1051 | '@typescript-eslint/typescript-estree@8.22.0(typescript@5.7.3)': 1052 | dependencies: 1053 | '@typescript-eslint/types': 8.22.0 1054 | '@typescript-eslint/visitor-keys': 8.22.0 1055 | debug: 4.4.0 1056 | fast-glob: 3.3.3 1057 | is-glob: 4.0.3 1058 | minimatch: 9.0.5 1059 | semver: 7.7.0 1060 | ts-api-utils: 2.0.1(typescript@5.7.3) 1061 | typescript: 5.7.3 1062 | transitivePeerDependencies: 1063 | - supports-color 1064 | 1065 | '@typescript-eslint/typescript-estree@8.25.0(typescript@5.7.3)': 1066 | dependencies: 1067 | '@typescript-eslint/types': 8.25.0 1068 | '@typescript-eslint/visitor-keys': 8.25.0 1069 | debug: 4.4.0 1070 | fast-glob: 3.3.3 1071 | is-glob: 4.0.3 1072 | minimatch: 9.0.5 1073 | semver: 7.7.1 1074 | ts-api-utils: 2.0.1(typescript@5.7.3) 1075 | typescript: 5.7.3 1076 | transitivePeerDependencies: 1077 | - supports-color 1078 | 1079 | '@typescript-eslint/utils@8.25.0(eslint@8.57.1)(typescript@5.7.3)': 1080 | dependencies: 1081 | '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) 1082 | '@typescript-eslint/scope-manager': 8.25.0 1083 | '@typescript-eslint/types': 8.25.0 1084 | '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.7.3) 1085 | eslint: 8.57.1 1086 | typescript: 5.7.3 1087 | transitivePeerDependencies: 1088 | - supports-color 1089 | 1090 | '@typescript-eslint/visitor-keys@8.22.0': 1091 | dependencies: 1092 | '@typescript-eslint/types': 8.22.0 1093 | eslint-visitor-keys: 4.2.0 1094 | 1095 | '@typescript-eslint/visitor-keys@8.25.0': 1096 | dependencies: 1097 | '@typescript-eslint/types': 8.25.0 1098 | eslint-visitor-keys: 4.2.0 1099 | 1100 | '@ungap/structured-clone@1.2.0': {} 1101 | 1102 | '@vercel/ncc@0.38.3': {} 1103 | 1104 | acorn-jsx@5.3.2(acorn@8.13.0): 1105 | dependencies: 1106 | acorn: 8.13.0 1107 | 1108 | acorn@8.13.0: {} 1109 | 1110 | ajv@6.12.6: 1111 | dependencies: 1112 | fast-deep-equal: 3.1.3 1113 | fast-json-stable-stringify: 2.1.0 1114 | json-schema-traverse: 0.4.1 1115 | uri-js: 4.4.1 1116 | 1117 | ansi-regex@5.0.1: {} 1118 | 1119 | ansi-styles@4.3.0: 1120 | dependencies: 1121 | color-convert: 2.0.1 1122 | 1123 | argparse@2.0.1: {} 1124 | 1125 | balanced-match@1.0.2: {} 1126 | 1127 | before-after-hook@2.2.3: {} 1128 | 1129 | brace-expansion@1.1.11: 1130 | dependencies: 1131 | balanced-match: 1.0.2 1132 | concat-map: 0.0.1 1133 | 1134 | brace-expansion@2.0.1: 1135 | dependencies: 1136 | balanced-match: 1.0.2 1137 | 1138 | braces@3.0.3: 1139 | dependencies: 1140 | fill-range: 7.1.1 1141 | 1142 | callsites@3.1.0: {} 1143 | 1144 | chalk@4.1.2: 1145 | dependencies: 1146 | ansi-styles: 4.3.0 1147 | supports-color: 7.2.0 1148 | 1149 | color-convert@2.0.1: 1150 | dependencies: 1151 | color-name: 1.1.4 1152 | 1153 | color-name@1.1.4: {} 1154 | 1155 | concat-map@0.0.1: {} 1156 | 1157 | cross-spawn@7.0.3: 1158 | dependencies: 1159 | path-key: 3.1.1 1160 | shebang-command: 2.0.0 1161 | which: 2.0.2 1162 | 1163 | data-uri-to-buffer@4.0.1: {} 1164 | 1165 | debug@4.3.7: 1166 | dependencies: 1167 | ms: 2.1.3 1168 | 1169 | debug@4.4.0: 1170 | dependencies: 1171 | ms: 2.1.3 1172 | 1173 | deep-is@0.1.4: {} 1174 | 1175 | deprecation@2.3.1: {} 1176 | 1177 | doctrine@3.0.0: 1178 | dependencies: 1179 | esutils: 2.0.3 1180 | 1181 | dotenv@16.4.7: {} 1182 | 1183 | entities@4.5.0: {} 1184 | 1185 | escape-string-regexp@4.0.0: {} 1186 | 1187 | eslint-config-prettier@10.0.1(eslint@8.57.1): 1188 | dependencies: 1189 | eslint: 8.57.1 1190 | 1191 | eslint-plugin-prettier@5.2.3(eslint-config-prettier@10.0.1(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.2): 1192 | dependencies: 1193 | eslint: 8.57.1 1194 | prettier: 3.5.2 1195 | prettier-linter-helpers: 1.0.0 1196 | synckit: 0.9.2 1197 | optionalDependencies: 1198 | eslint-config-prettier: 10.0.1(eslint@8.57.1) 1199 | 1200 | eslint-scope@7.2.2: 1201 | dependencies: 1202 | esrecurse: 4.3.0 1203 | estraverse: 5.3.0 1204 | 1205 | eslint-visitor-keys@3.4.3: {} 1206 | 1207 | eslint-visitor-keys@4.2.0: {} 1208 | 1209 | eslint@8.57.1: 1210 | dependencies: 1211 | '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) 1212 | '@eslint-community/regexpp': 4.11.1 1213 | '@eslint/eslintrc': 2.1.4 1214 | '@eslint/js': 8.57.1 1215 | '@humanwhocodes/config-array': 0.13.0 1216 | '@humanwhocodes/module-importer': 1.0.1 1217 | '@nodelib/fs.walk': 1.2.8 1218 | '@ungap/structured-clone': 1.2.0 1219 | ajv: 6.12.6 1220 | chalk: 4.1.2 1221 | cross-spawn: 7.0.3 1222 | debug: 4.3.7 1223 | doctrine: 3.0.0 1224 | escape-string-regexp: 4.0.0 1225 | eslint-scope: 7.2.2 1226 | eslint-visitor-keys: 3.4.3 1227 | espree: 9.6.1 1228 | esquery: 1.6.0 1229 | esutils: 2.0.3 1230 | fast-deep-equal: 3.1.3 1231 | file-entry-cache: 6.0.1 1232 | find-up: 5.0.0 1233 | glob-parent: 6.0.2 1234 | globals: 13.24.0 1235 | graphemer: 1.4.0 1236 | ignore: 5.3.2 1237 | imurmurhash: 0.1.4 1238 | is-glob: 4.0.3 1239 | is-path-inside: 3.0.3 1240 | js-yaml: 4.1.0 1241 | json-stable-stringify-without-jsonify: 1.0.1 1242 | levn: 0.4.1 1243 | lodash.merge: 4.6.2 1244 | minimatch: 3.1.2 1245 | natural-compare: 1.4.0 1246 | optionator: 0.9.4 1247 | strip-ansi: 6.0.1 1248 | text-table: 0.2.0 1249 | transitivePeerDependencies: 1250 | - supports-color 1251 | 1252 | espree@9.6.1: 1253 | dependencies: 1254 | acorn: 8.13.0 1255 | acorn-jsx: 5.3.2(acorn@8.13.0) 1256 | eslint-visitor-keys: 3.4.3 1257 | 1258 | esquery@1.6.0: 1259 | dependencies: 1260 | estraverse: 5.3.0 1261 | 1262 | esrecurse@4.3.0: 1263 | dependencies: 1264 | estraverse: 5.3.0 1265 | 1266 | estraverse@5.3.0: {} 1267 | 1268 | esutils@2.0.3: {} 1269 | 1270 | fast-content-type-parse@2.0.1: {} 1271 | 1272 | fast-deep-equal@3.1.3: {} 1273 | 1274 | fast-diff@1.3.0: {} 1275 | 1276 | fast-glob@3.3.3: 1277 | dependencies: 1278 | '@nodelib/fs.stat': 2.0.5 1279 | '@nodelib/fs.walk': 1.2.8 1280 | glob-parent: 5.1.2 1281 | merge2: 1.4.1 1282 | micromatch: 4.0.8 1283 | 1284 | fast-json-stable-stringify@2.1.0: {} 1285 | 1286 | fast-levenshtein@2.0.6: {} 1287 | 1288 | fastq@1.17.1: 1289 | dependencies: 1290 | reusify: 1.0.4 1291 | 1292 | fetch-blob@3.2.0: 1293 | dependencies: 1294 | node-domexception: 1.0.0 1295 | web-streams-polyfill: 3.3.3 1296 | 1297 | file-entry-cache@6.0.1: 1298 | dependencies: 1299 | flat-cache: 3.2.0 1300 | 1301 | fill-range@7.1.1: 1302 | dependencies: 1303 | to-regex-range: 5.0.1 1304 | 1305 | find-up@5.0.0: 1306 | dependencies: 1307 | locate-path: 6.0.0 1308 | path-exists: 4.0.0 1309 | 1310 | flat-cache@3.2.0: 1311 | dependencies: 1312 | flatted: 3.3.1 1313 | keyv: 4.5.4 1314 | rimraf: 3.0.2 1315 | 1316 | flatted@3.3.1: {} 1317 | 1318 | formdata-polyfill@4.0.10: 1319 | dependencies: 1320 | fetch-blob: 3.2.0 1321 | 1322 | fs.realpath@1.0.0: {} 1323 | 1324 | glob-parent@5.1.2: 1325 | dependencies: 1326 | is-glob: 4.0.3 1327 | 1328 | glob-parent@6.0.2: 1329 | dependencies: 1330 | is-glob: 4.0.3 1331 | 1332 | glob@7.2.3: 1333 | dependencies: 1334 | fs.realpath: 1.0.0 1335 | inflight: 1.0.6 1336 | inherits: 2.0.4 1337 | minimatch: 3.1.2 1338 | once: 1.4.0 1339 | path-is-absolute: 1.0.1 1340 | 1341 | globals@13.24.0: 1342 | dependencies: 1343 | type-fest: 0.20.2 1344 | 1345 | graphemer@1.4.0: {} 1346 | 1347 | has-flag@4.0.0: {} 1348 | 1349 | ignore@5.3.2: {} 1350 | 1351 | import-fresh@3.3.0: 1352 | dependencies: 1353 | parent-module: 1.0.1 1354 | resolve-from: 4.0.0 1355 | 1356 | imurmurhash@0.1.4: {} 1357 | 1358 | inflight@1.0.6: 1359 | dependencies: 1360 | once: 1.4.0 1361 | wrappy: 1.0.2 1362 | 1363 | inherits@2.0.4: {} 1364 | 1365 | is-extglob@2.1.1: {} 1366 | 1367 | is-glob@4.0.3: 1368 | dependencies: 1369 | is-extglob: 2.1.1 1370 | 1371 | is-number@7.0.0: {} 1372 | 1373 | is-path-inside@3.0.3: {} 1374 | 1375 | isexe@2.0.0: {} 1376 | 1377 | js-yaml@4.1.0: 1378 | dependencies: 1379 | argparse: 2.0.1 1380 | 1381 | json-buffer@3.0.1: {} 1382 | 1383 | json-schema-traverse@0.4.1: {} 1384 | 1385 | json-stable-stringify-without-jsonify@1.0.1: {} 1386 | 1387 | keyv@4.5.4: 1388 | dependencies: 1389 | json-buffer: 3.0.1 1390 | 1391 | levn@0.4.1: 1392 | dependencies: 1393 | prelude-ls: 1.2.1 1394 | type-check: 0.4.0 1395 | 1396 | locate-path@6.0.0: 1397 | dependencies: 1398 | p-locate: 5.0.0 1399 | 1400 | lodash.merge@4.6.2: {} 1401 | 1402 | merge2@1.4.1: {} 1403 | 1404 | micromatch@4.0.8: 1405 | dependencies: 1406 | braces: 3.0.3 1407 | picomatch: 2.3.1 1408 | 1409 | minimatch@3.1.2: 1410 | dependencies: 1411 | brace-expansion: 1.1.11 1412 | 1413 | minimatch@9.0.5: 1414 | dependencies: 1415 | brace-expansion: 2.0.1 1416 | 1417 | ms@2.1.3: {} 1418 | 1419 | natural-compare@1.4.0: {} 1420 | 1421 | node-domexception@1.0.0: {} 1422 | 1423 | node-fetch@3.3.2: 1424 | dependencies: 1425 | data-uri-to-buffer: 4.0.1 1426 | fetch-blob: 3.2.0 1427 | formdata-polyfill: 4.0.10 1428 | 1429 | once@1.4.0: 1430 | dependencies: 1431 | wrappy: 1.0.2 1432 | 1433 | optionator@0.9.4: 1434 | dependencies: 1435 | deep-is: 0.1.4 1436 | fast-levenshtein: 2.0.6 1437 | levn: 0.4.1 1438 | prelude-ls: 1.2.1 1439 | type-check: 0.4.0 1440 | word-wrap: 1.2.5 1441 | 1442 | p-limit@3.1.0: 1443 | dependencies: 1444 | yocto-queue: 0.1.0 1445 | 1446 | p-locate@5.0.0: 1447 | dependencies: 1448 | p-limit: 3.1.0 1449 | 1450 | parent-module@1.0.1: 1451 | dependencies: 1452 | callsites: 3.1.0 1453 | 1454 | parse5@7.2.0: 1455 | dependencies: 1456 | entities: 4.5.0 1457 | 1458 | path-exists@4.0.0: {} 1459 | 1460 | path-is-absolute@1.0.1: {} 1461 | 1462 | path-key@3.1.1: {} 1463 | 1464 | picomatch@2.3.1: {} 1465 | 1466 | prelude-ls@1.2.1: {} 1467 | 1468 | prettier-linter-helpers@1.0.0: 1469 | dependencies: 1470 | fast-diff: 1.3.0 1471 | 1472 | prettier@3.5.2: {} 1473 | 1474 | punycode@2.3.1: {} 1475 | 1476 | queue-microtask@1.2.3: {} 1477 | 1478 | resolve-from@4.0.0: {} 1479 | 1480 | reusify@1.0.4: {} 1481 | 1482 | rimraf@3.0.2: 1483 | dependencies: 1484 | glob: 7.2.3 1485 | 1486 | run-parallel@1.2.0: 1487 | dependencies: 1488 | queue-microtask: 1.2.3 1489 | 1490 | semver@7.7.0: {} 1491 | 1492 | semver@7.7.1: {} 1493 | 1494 | shebang-command@2.0.0: 1495 | dependencies: 1496 | shebang-regex: 3.0.0 1497 | 1498 | shebang-regex@3.0.0: {} 1499 | 1500 | simple-git@3.27.0: 1501 | dependencies: 1502 | '@kwsites/file-exists': 1.1.1 1503 | '@kwsites/promise-deferred': 1.1.1 1504 | debug: 4.3.7 1505 | transitivePeerDependencies: 1506 | - supports-color 1507 | 1508 | strip-ansi@6.0.1: 1509 | dependencies: 1510 | ansi-regex: 5.0.1 1511 | 1512 | strip-json-comments@3.1.1: {} 1513 | 1514 | supports-color@7.2.0: 1515 | dependencies: 1516 | has-flag: 4.0.0 1517 | 1518 | synckit@0.9.2: 1519 | dependencies: 1520 | '@pkgr/core': 0.1.1 1521 | tslib: 2.8.1 1522 | 1523 | text-table@0.2.0: {} 1524 | 1525 | to-regex-range@5.0.1: 1526 | dependencies: 1527 | is-number: 7.0.0 1528 | 1529 | ts-api-utils@2.0.1(typescript@5.7.3): 1530 | dependencies: 1531 | typescript: 5.7.3 1532 | 1533 | tslib@2.8.1: {} 1534 | 1535 | tunnel@0.0.6: {} 1536 | 1537 | type-check@0.4.0: 1538 | dependencies: 1539 | prelude-ls: 1.2.1 1540 | 1541 | type-fest@0.20.2: {} 1542 | 1543 | typescript@5.7.3: {} 1544 | 1545 | undici-types@6.20.0: {} 1546 | 1547 | undici@5.28.4: 1548 | dependencies: 1549 | '@fastify/busboy': 2.1.1 1550 | 1551 | universal-user-agent@6.0.1: {} 1552 | 1553 | universal-user-agent@7.0.2: {} 1554 | 1555 | uri-js@4.4.1: 1556 | dependencies: 1557 | punycode: 2.3.1 1558 | 1559 | web-streams-polyfill@3.3.3: {} 1560 | 1561 | which@2.0.2: 1562 | dependencies: 1563 | isexe: 2.0.0 1564 | 1565 | word-wrap@1.2.5: {} 1566 | 1567 | wrappy@1.0.2: {} 1568 | 1569 | yocto-queue@0.1.0: {} 1570 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core' 2 | import * as github from '@actions/github' 3 | import type { GraphQlQueryResponseData } from '@octokit/graphql' 4 | import fetch from 'node-fetch' 5 | 6 | import { finished } from 'stream/promises' 7 | 8 | import sgit from 'simple-git' 9 | import fs from 'fs/promises' 10 | import path from 'path' 11 | 12 | process.on('unhandledRejection', (error) => { 13 | throw error 14 | }) 15 | 16 | enum DevCardType { 17 | Vertical = 'default', 18 | Horizontal = 'wide', 19 | } 20 | 21 | const devcardURL = (user_id: string, type: DevCardType = DevCardType.Vertical): string => 22 | `https://api.daily.dev/devcards/v2/${user_id}.png?type=${type}&r=${new Date().valueOf()}&ref=action` 23 | 24 | // Function to validate PNG file signature 25 | async function isPNG(filePath: string): Promise { 26 | try { 27 | const buffer = await fs.readFile(filePath) 28 | // Check PNG signature (magic numbers) 29 | return ( 30 | buffer.length >= 8 && 31 | buffer[0] === 0x89 && // PNG signature start 32 | buffer[1] === 0x50 && // P 33 | buffer[2] === 0x4e && // N 34 | buffer[3] === 0x47 && // G 35 | buffer[4] === 0x0d && // CR 36 | buffer[5] === 0x0a && // LF 37 | buffer[6] === 0x1a && // EOF 38 | buffer[7] === 0x0a // LF 39 | ) 40 | } catch (error) { 41 | console.debug('Error validating PNG file:', error) 42 | return false 43 | } 44 | } 45 | 46 | ;(async function () { 47 | try { 48 | const user_id = core.getInput('user_id') 49 | const type = core.getInput('type') as DevCardType 50 | const token = core.getInput('token') 51 | const branch = core.getInput('commit_branch') 52 | const message = core.getInput('commit_message') 53 | const filename = core.getInput('commit_filename') 54 | const email = core.getInput('committer_email') 55 | const name = core.getInput('committer_name') 56 | const dryrun = core.getBooleanInput('dryrun') 57 | 58 | // throw an error if filename is empty 59 | if (!filename || filename.length === 0) { 60 | throw new Error('Filename is required') 61 | } 62 | 63 | // throw an error if type is invalid, must be either "default" or "wide" 64 | if (type && !Object.values(DevCardType).includes(type)) { 65 | throw new Error('Invalid type') 66 | } 67 | 68 | console.log(`Dryrun`, dryrun) 69 | 70 | // Fetch the latest devcard 71 | try { 72 | const { body } = await fetch(devcardURL(user_id, type)) 73 | if (body === null) { 74 | const message = `Empty response from devcard URL: ${devcardURL(user_id, type)}` 75 | core.setFailed(message) 76 | console.debug(message) 77 | process.exit(1) 78 | } 79 | 80 | await fs.mkdir(path.dirname(path.join(`/tmp`, filename)), { 81 | recursive: true, 82 | }) 83 | const file = await fs.open(path.join(`/tmp`, filename), 'w') 84 | const stream = file.createWriteStream() 85 | await finished(body.pipe(stream)) 86 | await file.close() 87 | console.log(`Saved to ${path.join(`/tmp`, filename)}`, 'ok') 88 | 89 | // Validate that the downloaded file is actually a PNG 90 | const isPngFile = await isPNG(path.join(`/tmp`, filename)) 91 | if (!isPngFile) { 92 | const message = `Invalid file format: The downloaded file is not a valid PNG image` 93 | core.setFailed(message) 94 | console.debug(message) 95 | process.exit(1) 96 | } 97 | console.log('PNG validation check passed') 98 | } catch (error) { 99 | console.debug(error) 100 | } 101 | 102 | const committer = { 103 | commit: true, 104 | message: message.replace(/[$][{]filename[}]/g, filename), 105 | branch: branch || github.context.ref.replace(/^refs[/]heads[/]/, ''), 106 | sha: undefined, 107 | email: email, 108 | name: name, 109 | } 110 | 111 | const octokit = github.getOctokit(token) 112 | console.log('Committer REST API', 'ok') 113 | try { 114 | console.log('Committer account', (await octokit.rest.users.getAuthenticated()).data.login) 115 | } catch { 116 | console.log('Committer account', '(github-actions)') 117 | } 118 | 119 | console.log('Using branch', committer.branch) 120 | 121 | //Create head branch if needed 122 | try { 123 | await octokit.rest.git.getRef({ 124 | ...github.context.repo, 125 | ref: `heads/${committer.branch}`, 126 | }) 127 | console.log('Committer head branch status', 'ok') 128 | } catch (error) { 129 | if (/not found/i.test(`${error}`)) { 130 | const { 131 | data: { object }, 132 | } = await octokit.rest.git.getRef({ 133 | ...github.context.repo, 134 | ref: github.context.ref.replace(/^refs[/]/, ''), 135 | }) 136 | 137 | console.log('Committer branch current sha', object.sha) 138 | await octokit.rest.git.createRef({ 139 | ...github.context.repo, 140 | ref: `refs/heads/${committer.branch}`, 141 | sha: object.sha, 142 | }) 143 | console.log('Committer head branch status', '(created)') 144 | } else throw error 145 | } 146 | 147 | // Retrieve previous SHA of devcard file to be able to update content through the API 148 | try { 149 | const { 150 | repository: { 151 | object: { oid }, 152 | }, 153 | } = await octokit.graphql( 154 | ` 155 | query Sha { 156 | repository(owner: "${github.context.repo.owner}", name: "${github.context.repo.repo}") { 157 | object(expression: "${committer.branch}:${filename}") { ... on Blob { oid } } 158 | } 159 | } 160 | `, 161 | { headers: { authorization: `token ${token}` } }, 162 | ) 163 | committer.sha = oid 164 | } catch (error) { 165 | console.debug(error) 166 | } 167 | console.log('Previous render sha', committer.sha ?? '(none)') 168 | 169 | // Compare previous to current devcard 170 | const git = sgit() 171 | const sha = await git.hashObject(path.join(`/tmp`, filename)) 172 | console.log('Current devcard sha', sha) 173 | if (committer.sha === sha) { 174 | console.log(`Commit to branch ${committer.branch}`, '(no changes)') 175 | committer.commit = false 176 | } 177 | 178 | if (committer.commit && !dryrun) { 179 | const fileContent = await fs.readFile(path.join(`/tmp`, filename)) 180 | await octokit.rest.repos.createOrUpdateFileContents({ 181 | ...github.context.repo, 182 | path: filename, 183 | message: committer.message, 184 | content: fileContent.toString('base64'), 185 | branch: committer.branch, 186 | committer: { name: committer.name, email: committer.email }, 187 | ...(committer.sha ? { sha: committer.sha } : {}), 188 | }) 189 | } 190 | } catch (error) { 191 | if (error instanceof Error) { 192 | core.setFailed(error.message) 193 | console.debug(error) 194 | process.exit(1) 195 | } 196 | } 197 | })() 198 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "noImplicitAny": true, 7 | "noUnusedLocals": true, 8 | "noUnusedParameters": true, 9 | "outDir": "./dist", 10 | "rootDir": "./src", 11 | "strict": true, 12 | "target": "es2021" 13 | }, 14 | "exclude": [ 15 | "node_modules", 16 | "**/*.test.ts" 17 | ] 18 | } 19 | --------------------------------------------------------------------------------