├── .dockerignore ├── .gitattributes ├── .github ├── FUNDING.yml ├── labels.yml └── workflows │ ├── docker.yml │ ├── test.yml │ ├── typings.yml │ └── website.yml ├── .gitignore ├── .gitmodules ├── .vscode ├── launch.json └── tasks.json ├── Dockerfile ├── ExportAPI ├── ExportAPI.csproj ├── Interceptors │ └── ExceptionInterceptor.cs ├── Program.cs ├── Protos │ └── export.proto ├── Services │ └── ExportService.cs ├── Startup.cs ├── Validators │ └── ExporterValidator.cs ├── appsettings.Development.json ├── appsettings.json └── util │ └── ExportOptions.cs ├── LICENSE ├── README.md ├── docker-compose.yml ├── typings ├── .gitignore ├── .yarn │ └── releases │ │ └── yarn-3.3.0.cjs ├── .yarnrc.yml ├── LICENSE ├── README.md ├── package.json ├── scripts │ └── build-protos.sh ├── src │ ├── client.ts │ └── types.ts ├── test │ └── index.ts ├── tsconfig.json └── yarn.lock └── website ├── .gitignore ├── README.md ├── babel.config.js ├── docs ├── api-versions │ ├── _category_.json │ ├── gRPC.md │ ├── v1.md │ └── v2.md ├── intro.md └── setup.md ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── sidebars.js ├── src ├── components │ └── HomepageFeatures │ │ ├── index.js │ │ └── styles.module.css ├── css │ └── custom.css └── pages │ ├── index.js │ ├── index.module.css │ └── markdown-page.md └── static ├── .nojekyll └── img ├── docusaurus.png ├── favicon.ico ├── logo.svg ├── quickstart.jpg ├── undraw_docusaurus_mountain.svg ├── undraw_docusaurus_react.svg └── undraw_docusaurus_tree.svg /.dockerignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | .git* 3 | docker-compose.yml 4 | Dockerfile 5 | **/bin/ 6 | **/obj/ 7 | typings 8 | website 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: Fyko 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: carterh 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | - name: help wanted 2 | color: "159818" 3 | - name: "meta: backport" 4 | color: ffe900 5 | - name: "meta: cleanup" 6 | color: ffe900 7 | - name: "meta: code style" 8 | color: ffe900 9 | - name: "meta: dependencies" 10 | color: ffe900 11 | - name: "meta: documentation" 12 | color: ffe900 13 | - name: "meta: examples" 14 | color: ffe900 15 | - name: "meta: meme" 16 | color: ffe900 17 | - name: "meta: refactor" 18 | color: ffe900 19 | - name: "meta: roadmap" 20 | color: ffe900 21 | - name: "meta: tests" 22 | color: ffe900 23 | - name: "meta: tooling" 24 | color: ffe900 25 | - name: "meta: v8" 26 | color: ffe900 27 | - name: "meta: webpack" 28 | color: ffe900 29 | - name: "p: high" 30 | color: d11f1f 31 | - name: "p: low" 32 | color: ffc9c9 33 | - name: "p: medium" 34 | color: ef6556 35 | - name: "s: already fixed" 36 | color: eebcff 37 | - name: "s: cannot reproduce" 38 | color: eebcff 39 | - name: "s: duplicate" 40 | color: eebcff 41 | - name: "s: in progress" 42 | color: eebcff 43 | - name: "s: invalid" 44 | color: eebcff 45 | - name: "s: potentially fixed" 46 | color: eebcff 47 | - name: "s: unverified" 48 | color: eebcff 49 | - name: "s: won't fix" 50 | color: eebcff 51 | - name: "semver: N/A" 52 | color: fff0db 53 | - name: "semver: major" 54 | color: ff8800 55 | - name: "semver: minor" 56 | color: fc9d2f 57 | - name: "semver: patch" 58 | color: ffb766 59 | - name: "t: error handling" 60 | color: "31e097" 61 | - name: "t: utility" 62 | color: "31e097" 63 | - name: "type: bug" 64 | color: af310e 65 | - name: "type: bugfix" 66 | color: af310e 67 | - name: "type: discussion" 68 | color: f8f8f8 69 | - name: "type: enhancement" 70 | color: 84b6eb 71 | - name: "type: typo" 72 | color: c5def5 73 | - name: web editor (test extensively) 74 | color: 006b75 75 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Docker Image 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | branches: [main] 8 | paths: 9 | - "ExportAPI/**" 10 | - "DiscordChatExporter/**" 11 | 12 | jobs: 13 | docker: 14 | name: Docker 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - name: Checkout submodules 21 | shell: bash 22 | run: | 23 | git config --global url."https://github.com/".insteadOf "git@github.com:" 24 | auth_header="$(git config --local --get http.https://github.com/.extraheader)" 25 | git submodule sync --recursive 26 | git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 27 | 28 | # if the commit is tagged, use the tag as the image tag 29 | - name: Set image tag 30 | id: image_tag 31 | run: | 32 | if [[ $GITHUB_REF == refs/tags/* ]]; then 33 | echo "::set-output name=tag::${GITHUB_REF#refs/tags/}" 34 | fi 35 | 36 | - name: Build 37 | id: build 38 | uses: redhat-actions/buildah-build@v2 39 | with: 40 | image: fyko/export-api 41 | tags: latest ${{ steps.image_tag.outputs.tag || '' }} ${{ github.sha }} 42 | dockerfiles: | 43 | ./Dockerfile 44 | build-args: | 45 | CREATED_AT=${{ env.datetime }} 46 | GITHUB_SHA=${{ github.sha }} 47 | 48 | - name: Publish 49 | uses: redhat-actions/push-to-registry@v2 50 | with: 51 | image: ${{ steps.build.outputs.image }} 52 | tags: ${{ steps.build.outputs.tags }} 53 | registry: ghcr.io 54 | username: ${{ github.actor }} 55 | password: ${{ secrets.GITHUB_TOKEN }} 56 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | 12 | - name: Setup .NET 13 | uses: actions/setup-dotnet@v1 14 | with: 15 | dotnet-version: 7.0.x 16 | 17 | - uses: actions/checkout@v2 18 | - name: Checkout submodules 19 | shell: bash 20 | run: | 21 | git config --global url."https://github.com/".insteadOf "git@github.com:" 22 | auth_header="$(git config --local --get http.https://github.com/.extraheader)" 23 | git submodule sync --recursive 24 | git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 25 | 26 | - name: Restore dependencies 27 | run: dotnet restore ./ExportAPI/ExportAPI.csproj 28 | 29 | - name: Build 30 | run: dotnet build --no-restore ./ExportAPI/ExportAPI.csproj 31 | 32 | - name: Test 33 | run: dotnet test --no-build --verbosity normal ./ExportAPI/ExportAPI.csproj 34 | -------------------------------------------------------------------------------- /.github/workflows/typings.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Client Package 2 | on: 3 | push: 4 | branches: [main] 5 | paths: 6 | - "typings/**" 7 | workflow_dispatch: 8 | 9 | jobs: 10 | package: 11 | name: Publish Client Package 12 | runs-on: ubuntu-latest 13 | defaults: 14 | run: 15 | working-directory: typings 16 | permissions: 17 | packages: write 18 | contents: read 19 | steps: 20 | - name: Checkout repository 21 | uses: actions/checkout@v2 22 | 23 | - name: Checkout submodules 24 | shell: bash 25 | run: | 26 | git config --global url."https://github.com/".insteadOf "git@github.com:" 27 | auth_header="$(git config --local --get http.https://github.com/.extraheader)" 28 | git submodule sync --recursive 29 | git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 30 | 31 | - name: Install Node v16 32 | uses: actions/setup-node@v1 33 | with: 34 | node-version: 16 35 | registry-url: https://registry.npmjs.org/ 36 | 37 | - name: Install dependencies 38 | run: yarn install --immutable 39 | 40 | - name: Build Client and Types 41 | run: yarn suite 42 | 43 | - name: Deploy to Github Package Registry 44 | run: yarn npm publish 45 | env: 46 | NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} 47 | -------------------------------------------------------------------------------- /.github/workflows/website.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Website to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | paths: 7 | - "website/**" 8 | workflow_dispatch: 9 | 10 | jobs: 11 | deploy: 12 | name: Deploy to GitHub Pages 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | 18 | - uses: actions/setup-node@v2 19 | with: 20 | node-version: 16.x 21 | cache: npm 22 | cache-dependency-path: 'website/package-lock.json' 23 | 24 | - name: Build website 25 | working-directory: website 26 | run: | 27 | npm ci 28 | npm run build 29 | 30 | # Popular action to deploy to GitHub Pages: 31 | # Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus 32 | - name: Deploy to GitHub Pages 33 | uses: peaceiris/actions-gh-pages@v3 34 | with: 35 | github_token: ${{ secrets.GITHUB_TOKEN }} 36 | # Build output to publish to the `gh-pages` branch: 37 | publish_dir: ./website/build 38 | # Assign commit authorship to the official GH-Actions bot for deploys to `gh-pages` branch: 39 | # https://github.com/actions/checkout/issues/13#issuecomment-724415212 40 | # The GH actions bot is used by default if you didn't specify the two fields. 41 | # You can swap them out with your own user credentials. 42 | user_name: github-actions[bot] 43 | user_email: 41898282+github-actions[bot]@users.noreply.github.com 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | 332 | app/ 333 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "DiscordChatExporter"] 2 | path = DiscordChatExporter 3 | url = git@github.com:Fyko/DiscordChatExporter.git 4 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to find out which attributes exist for C# debugging 3 | // Use hover for the description of the existing attributes 4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": ".NET Core Launch (web)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/ExportAPI/bin/Debug/net6.0/ExportAPI.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}/ExportAPI", 16 | "stopAtEntry": false, 17 | // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser 18 | "serverReadyAction": { 19 | "action": "openExternally", 20 | "pattern": "\\bNow listening on:\\s+(https?://\\S+)" 21 | }, 22 | "env": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | }, 25 | "sourceFileMap": { 26 | "/Views": "${workspaceFolder}/Views" 27 | } 28 | }, 29 | { 30 | "name": ".NET Core Attach", 31 | "type": "coreclr", 32 | "request": "attach", 33 | "processId": "${command:pickProcess}" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/ExportAPI/ExportAPI.csproj", 11 | "/property:GenerateFullPaths=true", 12 | "/consoleloggerparameters:NoSummary" 13 | ], 14 | "problemMatcher": "$msCompile" 15 | }, 16 | { 17 | "label": "publish", 18 | "command": "dotnet", 19 | "type": "process", 20 | "args": [ 21 | "publish", 22 | "${workspaceFolder}/ExportAPI/ExportAPI.csproj", 23 | "/property:GenerateFullPaths=true", 24 | "/consoleloggerparameters:NoSummary" 25 | ], 26 | "problemMatcher": "$msCompile" 27 | }, 28 | { 29 | "label": "watch", 30 | "command": "dotnet", 31 | "type": "process", 32 | "args": [ 33 | "watch", 34 | "run", 35 | "${workspaceFolder}/ExportAPI/ExportAPI.csproj", 36 | "/property:GenerateFullPaths=true", 37 | "/consoleloggerparameters:NoSummary" 38 | ], 39 | "problemMatcher": "$msCompile" 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Build 2 | FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build 3 | WORKDIR /source 4 | 5 | COPY . . 6 | 7 | WORKDIR /source/ExportAPI 8 | 9 | RUN dotnet restore 10 | RUN dotnet publish -c release -o /app --no-restore 11 | 12 | # Run 13 | FROM mcr.microsoft.com/dotnet/aspnet:7.0-alpine 14 | WORKDIR /app 15 | COPY --from=build /app . 16 | ENTRYPOINT ["dotnet", "ExportAPI.dll"] 17 | -------------------------------------------------------------------------------- /ExportAPI/ExportAPI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net7.0 4 | 4.0.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | all 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ExportAPI/Interceptors/ExceptionInterceptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Grpc.Core; 4 | using Grpc.Core.Interceptors; 5 | using Microsoft.Extensions.Logging; 6 | 7 | public class ExceptionInterceptor: Interceptor 8 | { 9 | private readonly ILogger _logger; 10 | 11 | public ExceptionInterceptor(ILogger logger) 12 | { 13 | _logger = logger; 14 | } 15 | 16 | public override async Task UnaryServerHandler( 17 | TRequest request, 18 | ServerCallContext context, 19 | UnaryServerMethod continuation) 20 | { 21 | try 22 | { 23 | return await continuation(request, context); 24 | } 25 | catch (Exception exception) 26 | { 27 | throw new RpcException(new Status(StatusCode.Internal, exception.ToString())); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /ExportAPI/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace ExportAPI 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IHostBuilder CreateHostBuilder(string[] args) => 14 | Host.CreateDefaultBuilder(args) 15 | .ConfigureWebHostDefaults(webBuilder => 16 | { 17 | webBuilder.UseStartup(); 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ExportAPI/Protos/export.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option csharp_namespace = "ExportAPI.Proto"; 4 | 5 | service Exporter { 6 | rpc CreateExport (CreateExportRequest) returns (stream CreateExportResponse); 7 | } 8 | 9 | enum ExportFormat { 10 | PlainText = 0; 11 | HtmlDark = 1; 12 | HtmlLight = 2; 13 | CSV = 3; 14 | JSON = 4; 15 | } 16 | 17 | message CreateExportRequest { 18 | string token = 1; 19 | string channel_id = 2; 20 | ExportFormat export_format = 3; 21 | string date_format = 4; 22 | string after = 5; 23 | string before = 6; 24 | } 25 | 26 | message CreateExportResponse { 27 | oneof ResponseType { 28 | double progress = 1; 29 | ExportComplete data = 2; 30 | } 31 | } 32 | 33 | message ExportComplete { 34 | int32 message_count = 1; 35 | bytes data = 2; 36 | } 37 | -------------------------------------------------------------------------------- /ExportAPI/Services/ExportService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using Grpc.Core; 5 | using Microsoft.Extensions.Logging; 6 | using ExportAPI.Proto; 7 | using DiscordChatExporter.Core.Discord; 8 | using DiscordChatExporter.Core.Exceptions; 9 | using DiscordChatExporter.Core.Exporting; 10 | using DiscordChatExporter.Core.Exporting.Partitioning; 11 | using DiscordChatExporter.Core.Exporting.Filtering; 12 | using DiscordChatExporter.Core.Discord.Data; 13 | using Gress; 14 | using Google.Protobuf; 15 | using Google.Protobuf.WellKnownTypes; 16 | 17 | namespace ExportAPI.Services; 18 | 19 | public class ExporterService : Exporter.ExporterBase 20 | { 21 | private readonly ILogger _logger; 22 | 23 | private const int ChunkSize = 1024 * 32; // 32 KB 24 | 25 | public ExporterService(ILoggerFactory loggerFactory) 26 | { 27 | _logger = loggerFactory.CreateLogger(); 28 | 29 | if (!Directory.Exists("/tmp/exports")) 30 | { 31 | Directory.CreateDirectory("/tmp/exports"); 32 | } 33 | 34 | var nowhex = DateTime.Now.Ticks.ToString("X2"); 35 | if (!Directory.Exists($"/tmp/exports/{nowhex}")) 36 | { 37 | Directory.CreateDirectory($"/tmp/exports/{nowhex}"); 38 | } 39 | } 40 | 41 | internal static string GetPath(string channelId, DiscordChatExporter.Core.Exporting.ExportFormat exportType) 42 | { 43 | var nowhex = DateTime.Now.Ticks.ToString("X2"); 44 | return $"/tmp/exports/{nowhex}/{channelId}.{exportType.GetFileExtension()}"; 45 | } 46 | 47 | internal void deleteFile(string path) 48 | { 49 | var exists = System.IO.File.Exists(path); 50 | if (exists) 51 | { 52 | try 53 | { 54 | System.IO.File.Delete(path); 55 | _logger.LogInformation($"Deleted {path}"); 56 | } 57 | catch { } 58 | } 59 | 60 | } 61 | 62 | public override async Task CreateExport(CreateExportRequest options, IServerStreamWriter responseStream, ServerCallContext context) 63 | { 64 | var ef = options.ExportFormat; 65 | var exportFormat = (DiscordChatExporter.Core.Exporting.ExportFormat)ef; 66 | 67 | var parsed = Snowflake.TryParse(options.ChannelId); 68 | var channelId = parsed ?? Snowflake.Zero; 69 | 70 | var client = new DiscordClient(options.Token); 71 | client._resolvedTokenKind = TokenKind.Bot; 72 | Channel channel; 73 | try 74 | { 75 | channel = await client.GetChannelAsync(channelId); 76 | } 77 | catch (DiscordChatExporterException e) 78 | { 79 | if (e.Message.Contains("Authentication")) 80 | { 81 | throw new RpcException(new Status(StatusCode.PermissionDenied, "An invalid Discord token was provided.")); 82 | } 83 | if (e.Message.Contains("Requested resource does not exist")) 84 | { 85 | throw new RpcException(new Status(StatusCode.NotFound, "A channel with the provided ID was not found.")); 86 | } 87 | throw new RpcException(new Status(StatusCode.Unknown, $"An unknown error occurred: {e.Message}")); 88 | } 89 | 90 | var guild = await client.GetGuildAsync(channel.GuildId); 91 | var res = await client.GetJsonResponseAsync("users/@me"); 92 | var me = DiscordChatExporter.Core.Discord.Data.User.Parse(res); 93 | 94 | var path = GetPath(channel.Id.ToString(), exportFormat); 95 | _logger.LogInformation($"[{me.FullName} ({me.Id})] Exporting #{channel.Name} ({channel.Id}) within {guild.Name} ({guild.Id}) to {path}"); 96 | var request = new ExportRequest( 97 | guild, 98 | channel, 99 | path, 100 | exportFormat, 101 | Snowflake.TryParse(options.After), 102 | Snowflake.TryParse(options.Before), 103 | PartitionLimit.Null, 104 | MessageFilter.Null, 105 | false, 106 | false, 107 | options.DateFormat 108 | ); 109 | 110 | var exporter = new ChannelExporter(client); 111 | 112 | _logger.LogInformation("Starting export"); 113 | var progress = new Progress(p => responseStream.WriteAsync(new CreateExportResponse { Progress = p.Value })); 114 | var messageCount = await exporter.ExportChannelAsync(request, progress); 115 | _logger.LogInformation("Finished exporting"); 116 | 117 | 118 | var buffer = new byte[ChunkSize]; 119 | await using var readStream = File.OpenRead(path); 120 | while (true) 121 | { 122 | var count = await readStream.ReadAsync(buffer); 123 | 124 | if (count == 0) 125 | { 126 | break; 127 | } 128 | 129 | Console.WriteLine("Sending file data chunk of length " + count); 130 | await responseStream.WriteAsync(new CreateExportResponse 131 | { 132 | Data = new ExportComplete { 133 | MessageCount = messageCount, 134 | Data = UnsafeByteOperations.UnsafeWrap(buffer.AsMemory(0, count)) 135 | } 136 | }); 137 | } 138 | 139 | deleteFile(path); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /ExportAPI/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | // using Calzolari.Grpc.AspNetCore.Validation; 6 | using Microsoft.Extensions.Hosting; 7 | using ExportAPI.Services; 8 | using ExportAPI.Validators; 9 | 10 | namespace ExportAPI 11 | { 12 | public class Startup 13 | { 14 | public Startup(IConfiguration configuration) 15 | { 16 | Configuration = configuration; 17 | } 18 | 19 | public IConfiguration Configuration { get; } 20 | 21 | // This method gets called by the runtime. Use this method to add services to the container. 22 | public void ConfigureServices(IServiceCollection services) 23 | { 24 | services.AddControllers(); 25 | 26 | services.AddGrpc(options => 27 | { 28 | options.Interceptors.Add(); 29 | }); 30 | services.AddGrpcReflection(); 31 | 32 | // services.AddValidator(); 33 | } 34 | 35 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 36 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 37 | { 38 | if (env.IsDevelopment()) 39 | { 40 | app.UseDeveloperExceptionPage(); 41 | } 42 | else 43 | { 44 | app.UseHsts(); 45 | } 46 | 47 | app.UseRouting(); 48 | 49 | app.UseEndpoints(endpoints => 50 | { 51 | endpoints.MapGrpcService(); 52 | endpoints.MapGrpcReflectionService(); 53 | }); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ExportAPI/Validators/ExporterValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using DiscordChatExporter.Core.Discord; 3 | using ExportAPI.Proto; 4 | 5 | namespace ExportAPI.Validators 6 | { 7 | public class CreateExportRequestValidator : AbstractValidator 8 | { 9 | public CreateExportRequestValidator() 10 | { 11 | RuleFor(request => request.Token).NotEmpty().WithMessage("A Discord token was not provided."); 12 | RuleFor(request => request.ChannelId).Must(channelId => { 13 | var parsed = Snowflake.TryParse(channelId); 14 | return parsed != null; 15 | }).WithMessage("A valid channel ID was not provided."); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /ExportAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Debug", 6 | "Grpc": "Debug", 7 | "Microsoft": "Debug" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ExportAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information" 5 | } 6 | }, 7 | "AllowedHosts": "*", 8 | "Kestrel": { 9 | "EndpointDefaults": { 10 | "Protocols": "Http2" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ExportAPI/util/ExportOptions.cs: -------------------------------------------------------------------------------- 1 | using DiscordChatExporter.Core.Exporting; 2 | 3 | namespace ExportAPI.Util 4 | { 5 | public class ExportOptions 6 | { 7 | public string token { get; set; } 8 | public string channel_id { get; set; } 9 | 10 | public string after { get; set; } 11 | 12 | public string before { get; set; } 13 | 14 | public ExportFormat export_format { get; set; } = ExportFormat.HtmlDark; 15 | 16 | public string date_format { get; set; } = "dd-MMM-yy hh:mm tt"; 17 | } 18 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Carter 'Fyko' Himmel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 📥 Discord Channel Exporter API 2 | > A gRPC service to create HTML exports of Discord text-channels. 3 | 4 | [![Docs](https://img.shields.io/badge/%F0%9F%93%96-Documentation-informational)](https://fyko.github.io/export-api/docs/intro) 5 | [![License](https://img.shields.io/github/license/fyko/export-api)](https://github.com/fyko/export-api/blob/master/LICENSE.md) 6 | [![Test](https://github.com/Fyko/export-api/workflows/Test/badge.svg)](https://github.com/Fyko/export-api/actions?query=workflow%3ATest) 7 | [![Docker Pulls](https://img.shields.io/badge/-Docker%20Image-grey?logo=docker)](https://github.com/Fyko/export-api/pkgs/container/export-api) 8 | [![Ko-fi Donate](https://img.shields.io/badge/kofi-donate-brightgreen.svg?label=Donate%20with%20Ko-fi&logo=ko-fi&colorB=F16061&link=https://ko-fi.com/carterh&logoColor=FFFFFF)](https://ko-fi.com/carterh) 9 | 10 | ## Usage 11 | ### Docker Image 12 | The Export API can be found on the [GitHub Container Registry](https://pkg.github.com) at [`fyko/export-api`](https://github.com/Fyko/export-api/pkgs/container/export-api). 13 | 14 | ```sh 15 | docker run -p yourport:80 --rm -it ghcr.io/fyko/export-api 16 | ``` 17 | or with Compose 18 | ```yaml 19 | services: 20 | exportapi: 21 | image: ghcr.io/fyko/export-api 22 | ports: 23 | - "yourport:80" 24 | expose: 25 | - "yourport" 26 | ``` 27 | 28 | ### Calling the gRPC API 29 | - [Documentation](https://fyko.github.io/export-api/docs/api-versions/gRPC) 30 | 31 | ## Thanks 32 | This services utilizes [`Tyrrrz/DiscordChatExporter`](https://github.com/Tyrrrz/DiscordChatExporter) for exporting channels. 33 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | services: 4 | exportapi: 5 | build: 6 | dockerfile: Dockerfile 7 | context: . 8 | ports: 9 | - "8080:80" 10 | expose: 11 | - "8080" 12 | -------------------------------------------------------------------------------- /typings/.gitignore: -------------------------------------------------------------------------------- 1 | # generated 2 | package.tgz 3 | 4 | generated 5 | 6 | client.js 7 | client.*map 8 | client.d.ts 9 | client.mjs 10 | 11 | types.js 12 | types.*map 13 | types.d.ts 14 | types.mjs 15 | 16 | # Logs 17 | logs 18 | *.log 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | lerna-debug.log* 23 | .pnpm-debug.log* 24 | 25 | # Diagnostic reports (https://nodejs.org/api/report.html) 26 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 27 | 28 | # Runtime data 29 | pids 30 | *.pid 31 | *.seed 32 | *.pid.lock 33 | 34 | # Directory for instrumented libs generated by jscoverage/JSCover 35 | lib-cov 36 | 37 | # Coverage directory used by tools like istanbul 38 | coverage 39 | *.lcov 40 | 41 | # nyc test coverage 42 | .nyc_output 43 | 44 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 45 | .grunt 46 | 47 | # Bower dependency directory (https://bower.io/) 48 | bower_components 49 | 50 | # node-waf configuration 51 | .lock-wscript 52 | 53 | # Compiled binary addons (https://nodejs.org/api/addons.html) 54 | build/Release 55 | 56 | # Dependency directories 57 | node_modules/ 58 | jspm_packages/ 59 | 60 | # Snowpack dependency directory (https://snowpack.dev/) 61 | web_modules/ 62 | 63 | # TypeScript cache 64 | *.tsbuildinfo 65 | 66 | # Optional npm cache directory 67 | .npm 68 | 69 | # Optional eslint cache 70 | .eslintcache 71 | 72 | # Optional stylelint cache 73 | .stylelintcache 74 | 75 | # Microbundle cache 76 | .rpt2_cache/ 77 | .rts2_cache_cjs/ 78 | .rts2_cache_es/ 79 | .rts2_cache_umd/ 80 | 81 | # Optional REPL history 82 | .node_repl_history 83 | 84 | # Output of 'npm pack' 85 | *.tgz 86 | 87 | # Yarn Integrity file 88 | .yarn-integrity 89 | 90 | # dotenv environment variable files 91 | .env 92 | .env.development.local 93 | .env.test.local 94 | .env.production.local 95 | .env.local 96 | 97 | # parcel-bundler cache (https://parceljs.org/) 98 | .cache 99 | .parcel-cache 100 | 101 | # Next.js build output 102 | .next 103 | out 104 | 105 | # Nuxt.js build / generate output 106 | .nuxt 107 | dist 108 | 109 | # Gatsby files 110 | .cache/ 111 | # Comment in the public line in if your project uses Gatsby and not Next.js 112 | # https://nextjs.org/blog/next-9-1#public-directory-support 113 | # public 114 | 115 | # vuepress build output 116 | .vuepress/dist 117 | 118 | # vuepress v2.x temp and cache directory 119 | .temp 120 | .cache 121 | 122 | # Docusaurus cache and generated files 123 | .docusaurus 124 | 125 | # Serverless directories 126 | .serverless/ 127 | 128 | # FuseBox cache 129 | .fusebox/ 130 | 131 | # DynamoDB Local files 132 | .dynamodb/ 133 | 134 | # TernJS port file 135 | .tern-port 136 | 137 | # Stores VSCode versions used for testing VSCode extensions 138 | .vscode-test 139 | 140 | # yarn v2 141 | .yarn/cache 142 | .yarn/unplugged 143 | .yarn/build-state.yml 144 | .yarn/install-state.gz 145 | .pnp.* 146 | !.yarn/releases 147 | !.yarn/plugns 148 | -------------------------------------------------------------------------------- /typings/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | enableGlobalCache: true 2 | 3 | nodeLinker: node-modules 4 | 5 | npmScopes: 6 | fyko: 7 | npmAlwaysAuth: false 8 | npmAuthToken: "${NODE_AUTH_TOKEN}" 9 | npmRegistryServer: "https://registry.npmjs.com" 10 | 11 | yarnPath: .yarn/releases/yarn-3.3.0.cjs 12 | -------------------------------------------------------------------------------- /typings/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Carter 'Fyko' Himmel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /typings/README.md: -------------------------------------------------------------------------------- 1 | # @fyko/export-api 2 | > Generated code for interacting with the [Export API](). 3 | 4 | 5 | ## Example 6 | ```ts 7 | import { credentials } from '@grpc/grpc-js'; 8 | import { ExporterClient } from '@fyko/export-api/client'; 9 | import { CreateExportRequest, CreateExportResponse, ExportFormat } from '@fyko/export-api/types'; 10 | import { writeFile } from 'fs/promises'; 11 | 12 | const client = new ExporterClient( 13 | `localhost:${process.env.PORT}`, 14 | credentials.createInsecure(), 15 | ); 16 | 17 | void (async () => { 18 | const request = new CreateExportRequest(); 19 | request.setChannelId(process.env.DISCORD_CHANNEL!); 20 | request.setToken(process.env.DISCORD_TOKEN!); 21 | request.setExportFormat(ExportFormat.HTMLDARK); 22 | 23 | return new Promise(async (res, rej) => { 24 | const stream = client.createExport(request); 25 | 26 | 27 | const chunks: (string | Uint8Array)[] = []; 28 | stream.on('data', (response: CreateExportResponse) => { 29 | const progress = response.getProgress() 30 | if (progress) console.log(progress); 31 | 32 | const data = response.getData(); 33 | const inner = data?.getData(); 34 | if (inner) { 35 | console.log(`Inner exists!`); 36 | chunks.push(inner); 37 | } 38 | }); 39 | 40 | stream.on('end', async () => { 41 | await writeFile('./foo.html', chunks); 42 | return res(void 0); 43 | }); 44 | 45 | stream.on('error', rej); 46 | }); 47 | })(); 48 | ``` -------------------------------------------------------------------------------- /typings/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fyko/export-api", 3 | "description": "Generated code for interacting with the Export API.", 4 | "version": "0.3.1", 5 | "license": "MIT", 6 | "exports": { 7 | "./client": { 8 | "require": "./dist/client.js", 9 | "import": "./dist/client.mjs", 10 | "types": "./dist/client.d.ts" 11 | }, 12 | "./types": { 13 | "require": "./dist/types.js", 14 | "import": "./dist/types.mjs", 15 | "types": "./dist/types.d.ts" 16 | } 17 | }, 18 | "files": [ 19 | "generated", 20 | "dist/{client,types}.{js,js.map,d.ts,d.ts.map,mjs}" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/Fyko/export-api.git", 25 | "directory": "typings" 26 | }, 27 | "scripts": { 28 | "suite": "yarn generate && tsc && run-p 'esm:*'", 29 | "build": "yarn generate && run-p 'esm:*'", 30 | "clean": "rimraf {client,types}.{js,mjs,d.ts,*map}", 31 | "generate": "./scripts/build-protos.sh ../ExportAPI/Protos/export.proto ./dist", 32 | "esm:client": "gen-esm-wrapper ./dist/client.js ./dist/client.mjs", 33 | "esm:types": "gen-esm-wrapper ./dist/types.js ./dist/types.mjs", 34 | "prepublish": "yarn suite" 35 | }, 36 | "dependencies": { 37 | "@grpc/grpc-js": "^1.2.2", 38 | "google-protobuf": "^3.19.4", 39 | "grpc-tools": "^1.10.0", 40 | "grpc_tools_node_protoc_ts": "^5.0.1", 41 | "typed-emitter": "^2.1.0" 42 | }, 43 | "devDependencies": { 44 | "gen-esm-wrapper": "^1.1.3", 45 | "npm-run-all": "^4.1.5", 46 | "rimraf": "^3.0.2", 47 | "typescript": "^4.5.5" 48 | }, 49 | "publishConfig": { 50 | "access": "public", 51 | "registry": "https://registry.npmjs.com" 52 | }, 53 | "packageManager": "yarn@3.3.0" 54 | } 55 | -------------------------------------------------------------------------------- /typings/scripts/build-protos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BASEDIR=$(dirname "$0") 4 | cd ${BASEDIR}/../ 5 | 6 | PROTO_DEST=./generated 7 | 8 | mkdir -p ${PROTO_DEST} 9 | 10 | # JavaScript code generation 11 | yarn run grpc_tools_node_protoc \ 12 | --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts \ 13 | --ts_out=grpc_js:${PROTO_DEST} \ 14 | --js_out=import_style=commonjs,binary:${PROTO_DEST} \ 15 | --grpc_out=grpc_js:${PROTO_DEST} \ 16 | -I ../ExportAPI/Protos \ 17 | ../ExportAPI/Protos/*.proto 18 | -------------------------------------------------------------------------------- /typings/src/client.ts: -------------------------------------------------------------------------------- 1 | export * from '../generated/export_grpc_pb'; 2 | 3 | import { CallOptions, ClientOptions, credentials } from "@grpc/grpc-js"; 4 | import { EventEmitter } from 'events'; 5 | import type TypedEmitter from "typed-emitter"; 6 | import { ExporterClient } from '../generated/export_grpc_pb'; 7 | import { CreateExportRequest, CreateExportResponse, ExportFormat } from './types'; 8 | 9 | export function createExporterClient( 10 | address: string, 11 | creds = credentials.createInsecure(), 12 | options?: ClientOptions 13 | ): ExporterClient { 14 | return new ExporterClient(address, creds, options); 15 | } 16 | 17 | export type ExportEvents = { 18 | error: (err: Error) => void; 19 | progress: (progress: number) => void; 20 | chunk: (chunk: string | Uint8Array) => void; 21 | done: (messageCount: number, file: Buffer) => void; 22 | } 23 | 24 | /** 25 | * Create an EventEmitter 26 | * @param client - The client to use to make the request 27 | * @param data - The data to provide to the request 28 | * @param options - Other gRPC options 29 | * @returns An EventEmitter 30 | * @see [Examples: High Level](https://fyko.github.io/export-api/docs/api-versions/gRPC#high-level) 31 | */ 32 | export function createExport( 33 | client: ExporterClient, 34 | data: CreateExportData, 35 | options?: Partial 36 | ) { 37 | const request = createExportRequest(data); 38 | const stream = client.createExport(request, options); 39 | 40 | const chunks: Uint8Array[] = []; 41 | 42 | let progress = 0; 43 | let messageCount: number | undefined = 0; 44 | const emitter = new EventEmitter() as TypedEmitter; 45 | 46 | stream.on('data', (response: CreateExportResponse) => { 47 | // if `response.progress` is present 48 | const p = response.getProgress(); 49 | if (p && p > progress) { 50 | progress = p; 51 | emitter.emit('progress', progress); 52 | } 53 | 54 | // if finally sending the file itself, push to chunk array 55 | const data = response.getData(); 56 | const count = data?.getMessageCount(); 57 | if (count) { 58 | messageCount = count; 59 | } 60 | 61 | const inner = data?.getData(); 62 | const isUint8Array = (x: unknown): x is Uint8Array => x instanceof Uint8Array; 63 | if (isUint8Array(inner)) { 64 | chunks.push(inner) 65 | } 66 | }); 67 | 68 | stream.on("end", async () => { 69 | stream.destroy(); 70 | return emitter.emit("done", messageCount ?? 0, Buffer.concat(chunks)); 71 | }); 72 | 73 | stream.on("error", (err) => { 74 | return emitter.emit('error', err); 75 | }); 76 | 77 | return emitter; 78 | } 79 | 80 | /** 81 | * Turns a stream into a promise that resolves with the message count and file buffer. 82 | * @param emitter - The emitter returned by `createExport` 83 | * @returns - A tuple of the message count and file buffer (in that order) 84 | */ 85 | export function promisifyExportResult(emitter: TypedEmitter) { 86 | return new Promise<[number, Buffer]>((resolve, reject) => { 87 | emitter.on("done", (count, file) => resolve([count, file])); 88 | emitter.on("error", (err) => reject(err)); 89 | }); 90 | } 91 | 92 | /** 93 | * The data to provide to the export request 94 | */ 95 | export interface CreateExportData { 96 | /** 97 | * The id of the channel to export 98 | */ 99 | channelId: string; 100 | /** 101 | * The bot token for performing requests 102 | */ 103 | token: string; 104 | /** 105 | * The format to export the channel as, defaults to PlainText 106 | */ 107 | exportFormat?: ExportFormat; 108 | /** 109 | * The [date format](https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings) for dates in exported files, defaults to dd-MMM-yy hh:mm tt 110 | */ 111 | dateFormat?: string; 112 | /** 113 | * Only include messages sent after this date 114 | */ 115 | after?: string; 116 | /** 117 | * Only include messages sent before this date 118 | */ 119 | before?: string; 120 | } 121 | 122 | /** 123 | * 124 | * @param data - The data to provide to the request 125 | * @returns A fresh `CreateExportRequest` 126 | */ 127 | function createExportRequest(data: CreateExportData) { 128 | const request = new CreateExportRequest(); 129 | 130 | request.setChannelId(data.channelId); 131 | request.setToken(data.token); 132 | 133 | if (data.exportFormat) 134 | request.setExportFormat(data.exportFormat); 135 | if (data.dateFormat) 136 | request.setDateFormat(data.dateFormat); 137 | if (data.after) 138 | request.setAfter(data.after); 139 | if (data.before) 140 | request.setBefore(data.before); 141 | 142 | return request; 143 | } 144 | -------------------------------------------------------------------------------- /typings/src/types.ts: -------------------------------------------------------------------------------- 1 | export * from '../generated/export_pb'; 2 | -------------------------------------------------------------------------------- /typings/test/index.ts: -------------------------------------------------------------------------------- 1 | import { writeFile } from "fs/promises"; 2 | import { createExport, createExporterClient, promisifyExportResult } from "../src/client"; 3 | import { 4 | ExportFormat 5 | } from "../src/types"; 6 | 7 | const client = createExporterClient(`localhost:${process.env.PORT}`); 8 | 9 | void (async () => { 10 | const stream = createExport(client, { 11 | channelId: process.env.DISCORD_CHANNEL!, 12 | token: process.env.DISCORD_TOKEN!, 13 | exportFormat: ExportFormat.HTMLDARK, 14 | }); 15 | 16 | stream.on("progress", (progress) => 17 | console.log(`progress: ${progress}`)); 18 | 19 | const [count, file] = await promisifyExportResult(stream); 20 | 21 | console.log(`export created with ${count} messages (${file.byteLength} bytes)`); 22 | await writeFile("./foo.html", file); 23 | })(); 24 | -------------------------------------------------------------------------------- /typings/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "alwaysStrict": true, 5 | "lib": ["esnext"], 6 | "module": "commonjs", 7 | "noUnusedParameters": true, 8 | "sourceMap": true, 9 | "declaration": true, 10 | "declarationMap": true, 11 | "moduleResolution": "node", 12 | "noUnusedLocals": true, 13 | "removeComments": true, 14 | "target": "ES2020", 15 | "importsNotUsedAsValues": "error", 16 | "strictNullChecks": true, 17 | "preserveConstEnums": true, 18 | "exactOptionalPropertyTypes": true, 19 | "outDir": "dist" 20 | }, 21 | "exclude": [ 22 | "node_modules", 23 | "test" 24 | ], 25 | "include": [ 26 | "src" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /typings/yarn.lock: -------------------------------------------------------------------------------- 1 | # This file is generated by running "yarn install" inside your project. 2 | # Manual changes might be lost - proceed with caution! 3 | 4 | __metadata: 5 | version: 6 6 | cacheKey: 8 7 | 8 | "@fyko/export-api@workspace:.": 9 | version: 0.0.0-use.local 10 | resolution: "@fyko/export-api@workspace:." 11 | dependencies: 12 | "@grpc/grpc-js": ^1.2.2 13 | gen-esm-wrapper: ^1.1.3 14 | google-protobuf: ^3.19.4 15 | grpc-tools: ^1.10.0 16 | grpc_tools_node_protoc_ts: ^5.0.1 17 | npm-run-all: ^4.1.5 18 | rimraf: ^3.0.2 19 | typed-emitter: ^2.1.0 20 | typescript: ^4.5.5 21 | languageName: unknown 22 | linkType: soft 23 | 24 | "@grpc/grpc-js@npm:^1.2.2": 25 | version: 1.5.5 26 | resolution: "@grpc/grpc-js@npm:1.5.5" 27 | dependencies: 28 | "@grpc/proto-loader": ^0.6.4 29 | "@types/node": ">=12.12.47" 30 | checksum: ccbe8267c150f98e4047bf74bf436ede71f05136697e6f299c1b9d005d133c6f132d67b392433298df884d9ebd639d08f9845b6cd2bfd9657d5704a78de281d0 31 | languageName: node 32 | linkType: hard 33 | 34 | "@grpc/proto-loader@npm:^0.6.4": 35 | version: 0.6.9 36 | resolution: "@grpc/proto-loader@npm:0.6.9" 37 | dependencies: 38 | "@types/long": ^4.0.1 39 | lodash.camelcase: ^4.3.0 40 | long: ^4.0.0 41 | protobufjs: ^6.10.0 42 | yargs: ^16.2.0 43 | bin: 44 | proto-loader-gen-types: build/bin/proto-loader-gen-types.js 45 | checksum: 30081a5a6e866506d8e799ebed00367024a2710b9b990104d804fe23c60d81d5ccaa74ad14bd0bedfab6fb313eccbc18e0bbcf3bda7f3288d8eb31cab040255f 46 | languageName: node 47 | linkType: hard 48 | 49 | "@mapbox/node-pre-gyp@npm:^1.0.5": 50 | version: 1.0.8 51 | resolution: "@mapbox/node-pre-gyp@npm:1.0.8" 52 | dependencies: 53 | detect-libc: ^1.0.3 54 | https-proxy-agent: ^5.0.0 55 | make-dir: ^3.1.0 56 | node-fetch: ^2.6.5 57 | nopt: ^5.0.0 58 | npmlog: ^5.0.1 59 | rimraf: ^3.0.2 60 | semver: ^7.3.5 61 | tar: ^6.1.11 62 | bin: 63 | node-pre-gyp: bin/node-pre-gyp 64 | checksum: 29a38f39575107fa1665edf14defcfdf62e12bb38e9c27f7457ba42be84060125015171d12b8de3065155a465992f1854a363e2985f071fcbea9ff0701362b05 65 | languageName: node 66 | linkType: hard 67 | 68 | "@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": 69 | version: 1.1.2 70 | resolution: "@protobufjs/aspromise@npm:1.1.2" 71 | checksum: 011fe7ef0826b0fd1a95935a033a3c0fd08483903e1aa8f8b4e0704e3233406abb9ee25350ec0c20bbecb2aad8da0dcea58b392bbd77d6690736f02c143865d2 72 | languageName: node 73 | linkType: hard 74 | 75 | "@protobufjs/base64@npm:^1.1.2": 76 | version: 1.1.2 77 | resolution: "@protobufjs/base64@npm:1.1.2" 78 | checksum: 67173ac34de1e242c55da52c2f5bdc65505d82453893f9b51dc74af9fe4c065cf4a657a4538e91b0d4a1a1e0a0642215e31894c31650ff6e3831471061e1ee9e 79 | languageName: node 80 | linkType: hard 81 | 82 | "@protobufjs/codegen@npm:^2.0.4": 83 | version: 2.0.4 84 | resolution: "@protobufjs/codegen@npm:2.0.4" 85 | checksum: 59240c850b1d3d0b56d8f8098dd04787dcaec5c5bd8de186fa548de86b86076e1c50e80144b90335e705a044edf5bc8b0998548474c2a10a98c7e004a1547e4b 86 | languageName: node 87 | linkType: hard 88 | 89 | "@protobufjs/eventemitter@npm:^1.1.0": 90 | version: 1.1.0 91 | resolution: "@protobufjs/eventemitter@npm:1.1.0" 92 | checksum: 0369163a3d226851682f855f81413cbf166cd98f131edb94a0f67f79e75342d86e89df9d7a1df08ac28be2bc77e0a7f0200526bb6c2a407abbfee1f0262d5fd7 93 | languageName: node 94 | linkType: hard 95 | 96 | "@protobufjs/fetch@npm:^1.1.0": 97 | version: 1.1.0 98 | resolution: "@protobufjs/fetch@npm:1.1.0" 99 | dependencies: 100 | "@protobufjs/aspromise": ^1.1.1 101 | "@protobufjs/inquire": ^1.1.0 102 | checksum: 3fce7e09eb3f1171dd55a192066450f65324fd5f7cc01a431df01bb00d0a895e6bfb5b0c5561ce157ee1d886349c90703d10a4e11a1a256418ff591b969b3477 103 | languageName: node 104 | linkType: hard 105 | 106 | "@protobufjs/float@npm:^1.0.2": 107 | version: 1.0.2 108 | resolution: "@protobufjs/float@npm:1.0.2" 109 | checksum: 5781e1241270b8bd1591d324ca9e3a3128d2f768077a446187a049e36505e91bc4156ed5ac3159c3ce3d2ba3743dbc757b051b2d723eea9cd367bfd54ab29b2f 110 | languageName: node 111 | linkType: hard 112 | 113 | "@protobufjs/inquire@npm:^1.1.0": 114 | version: 1.1.0 115 | resolution: "@protobufjs/inquire@npm:1.1.0" 116 | checksum: ca06f02eaf65ca36fb7498fc3492b7fc087bfcc85c702bac5b86fad34b692bdce4990e0ef444c1e2aea8c034227bd1f0484be02810d5d7e931c55445555646f4 117 | languageName: node 118 | linkType: hard 119 | 120 | "@protobufjs/path@npm:^1.1.2": 121 | version: 1.1.2 122 | resolution: "@protobufjs/path@npm:1.1.2" 123 | checksum: 856eeb532b16a7aac071cacde5c5620df800db4c80cee6dbc56380524736205aae21e5ae47739114bf669ab5e8ba0e767a282ad894f3b5e124197cb9224445ee 124 | languageName: node 125 | linkType: hard 126 | 127 | "@protobufjs/pool@npm:^1.1.0": 128 | version: 1.1.0 129 | resolution: "@protobufjs/pool@npm:1.1.0" 130 | checksum: d6a34fbbd24f729e2a10ee915b74e1d77d52214de626b921b2d77288bd8f2386808da2315080f2905761527cceffe7ec34c7647bd21a5ae41a25e8212ff79451 131 | languageName: node 132 | linkType: hard 133 | 134 | "@protobufjs/utf8@npm:^1.1.0": 135 | version: 1.1.0 136 | resolution: "@protobufjs/utf8@npm:1.1.0" 137 | checksum: f9bf3163d13aaa3b6f5e6fbf37a116e094ea021c0e1f2a7ccd0e12a29e2ce08dafba4e8b36e13f8ed7397e1591610ce880ed1289af4d66cf4ace8a36a9557278 138 | languageName: node 139 | linkType: hard 140 | 141 | "@types/long@npm:^4.0.1": 142 | version: 4.0.1 143 | resolution: "@types/long@npm:4.0.1" 144 | checksum: ff9653c33f5000d0f131fd98a950a0343e2e33107dd067a97ac4a3b9678e1a2e39ea44772ad920f54ef6e8f107f76bc92c2584ba905a0dc4253282a4101166d0 145 | languageName: node 146 | linkType: hard 147 | 148 | "@types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0": 149 | version: 17.0.18 150 | resolution: "@types/node@npm:17.0.18" 151 | checksum: 6c4edfc2b3ba2342a9c3d56e934c5245948ab752f4dc04bd6790b9603e6ebc53bc4f5befc3662e207f7dba2ddd17ccf657f915e319ea7cdd4f77b851079d1611 152 | languageName: node 153 | linkType: hard 154 | 155 | "abbrev@npm:1": 156 | version: 1.1.1 157 | resolution: "abbrev@npm:1.1.1" 158 | checksum: a4a97ec07d7ea112c517036882b2ac22f3109b7b19077dc656316d07d308438aac28e4d9746dc4d84bf6b1e75b4a7b0a5f3cb30592419f128ca9a8cee3bcfa17 159 | languageName: node 160 | linkType: hard 161 | 162 | "agent-base@npm:6": 163 | version: 6.0.2 164 | resolution: "agent-base@npm:6.0.2" 165 | dependencies: 166 | debug: 4 167 | checksum: f52b6872cc96fd5f622071b71ef200e01c7c4c454ee68bc9accca90c98cfb39f2810e3e9aa330435835eedc8c23f4f8a15267f67c6e245d2b33757575bdac49d 168 | languageName: node 169 | linkType: hard 170 | 171 | "ansi-regex@npm:^5.0.1": 172 | version: 5.0.1 173 | resolution: "ansi-regex@npm:5.0.1" 174 | checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b 175 | languageName: node 176 | linkType: hard 177 | 178 | "ansi-styles@npm:^3.2.1": 179 | version: 3.2.1 180 | resolution: "ansi-styles@npm:3.2.1" 181 | dependencies: 182 | color-convert: ^1.9.0 183 | checksum: d85ade01c10e5dd77b6c89f34ed7531da5830d2cb5882c645f330079975b716438cd7ebb81d0d6e6b4f9c577f19ae41ab55f07f19786b02f9dfd9e0377395665 184 | languageName: node 185 | linkType: hard 186 | 187 | "ansi-styles@npm:^4.0.0": 188 | version: 4.3.0 189 | resolution: "ansi-styles@npm:4.3.0" 190 | dependencies: 191 | color-convert: ^2.0.1 192 | checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4 193 | languageName: node 194 | linkType: hard 195 | 196 | "aproba@npm:^1.0.3 || ^2.0.0": 197 | version: 2.0.0 198 | resolution: "aproba@npm:2.0.0" 199 | checksum: 5615cadcfb45289eea63f8afd064ab656006361020e1735112e346593856f87435e02d8dcc7ff0d11928bc7d425f27bc7c2a84f6c0b35ab0ff659c814c138a24 200 | languageName: node 201 | linkType: hard 202 | 203 | "are-we-there-yet@npm:^2.0.0": 204 | version: 2.0.0 205 | resolution: "are-we-there-yet@npm:2.0.0" 206 | dependencies: 207 | delegates: ^1.0.0 208 | readable-stream: ^3.6.0 209 | checksum: 6c80b4fd04ecee6ba6e737e0b72a4b41bdc64b7d279edfc998678567ff583c8df27e27523bc789f2c99be603ffa9eaa612803da1d886962d2086e7ff6fa90c7c 210 | languageName: node 211 | linkType: hard 212 | 213 | "assert@npm:^1.4.1": 214 | version: 1.5.0 215 | resolution: "assert@npm:1.5.0" 216 | dependencies: 217 | object-assign: ^4.1.1 218 | util: 0.10.3 219 | checksum: 9be48435f726029ae7020c5888a3566bf4d617687aab280827f2e4029644b6515a9519ea10d018b342147c02faf73d9e9419e780e8937b3786ee4945a0ca71e5 220 | languageName: node 221 | linkType: hard 222 | 223 | "balanced-match@npm:^1.0.0": 224 | version: 1.0.2 225 | resolution: "balanced-match@npm:1.0.2" 226 | checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 227 | languageName: node 228 | linkType: hard 229 | 230 | "brace-expansion@npm:^1.1.7": 231 | version: 1.1.11 232 | resolution: "brace-expansion@npm:1.1.11" 233 | dependencies: 234 | balanced-match: ^1.0.0 235 | concat-map: 0.0.1 236 | checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 237 | languageName: node 238 | linkType: hard 239 | 240 | "call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": 241 | version: 1.0.2 242 | resolution: "call-bind@npm:1.0.2" 243 | dependencies: 244 | function-bind: ^1.1.1 245 | get-intrinsic: ^1.0.2 246 | checksum: f8e31de9d19988a4b80f3e704788c4a2d6b6f3d17cfec4f57dc29ced450c53a49270dc66bf0fbd693329ee948dd33e6c90a329519aef17474a4d961e8d6426b0 247 | languageName: node 248 | linkType: hard 249 | 250 | "chalk@npm:^2.4.1": 251 | version: 2.4.2 252 | resolution: "chalk@npm:2.4.2" 253 | dependencies: 254 | ansi-styles: ^3.2.1 255 | escape-string-regexp: ^1.0.5 256 | supports-color: ^5.3.0 257 | checksum: ec3661d38fe77f681200f878edbd9448821924e0f93a9cefc0e26a33b145f1027a2084bf19967160d11e1f03bfe4eaffcabf5493b89098b2782c3fe0b03d80c2 258 | languageName: node 259 | linkType: hard 260 | 261 | "chownr@npm:^2.0.0": 262 | version: 2.0.0 263 | resolution: "chownr@npm:2.0.0" 264 | checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f 265 | languageName: node 266 | linkType: hard 267 | 268 | "cliui@npm:^7.0.2": 269 | version: 7.0.4 270 | resolution: "cliui@npm:7.0.4" 271 | dependencies: 272 | string-width: ^4.2.0 273 | strip-ansi: ^6.0.0 274 | wrap-ansi: ^7.0.0 275 | checksum: ce2e8f578a4813806788ac399b9e866297740eecd4ad1823c27fd344d78b22c5f8597d548adbcc46f0573e43e21e751f39446c5a5e804a12aace402b7a315d7f 276 | languageName: node 277 | linkType: hard 278 | 279 | "color-convert@npm:^1.9.0": 280 | version: 1.9.3 281 | resolution: "color-convert@npm:1.9.3" 282 | dependencies: 283 | color-name: 1.1.3 284 | checksum: fd7a64a17cde98fb923b1dd05c5f2e6f7aefda1b60d67e8d449f9328b4e53b228a428fd38bfeaeb2db2ff6b6503a776a996150b80cdf224062af08a5c8a3a203 285 | languageName: node 286 | linkType: hard 287 | 288 | "color-convert@npm:^2.0.1": 289 | version: 2.0.1 290 | resolution: "color-convert@npm:2.0.1" 291 | dependencies: 292 | color-name: ~1.1.4 293 | checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336 294 | languageName: node 295 | linkType: hard 296 | 297 | "color-name@npm:1.1.3": 298 | version: 1.1.3 299 | resolution: "color-name@npm:1.1.3" 300 | checksum: 09c5d3e33d2105850153b14466501f2bfb30324a2f76568a408763a3b7433b0e50e5b4ab1947868e65cb101bb7cb75029553f2c333b6d4b8138a73fcc133d69d 301 | languageName: node 302 | linkType: hard 303 | 304 | "color-name@npm:~1.1.4": 305 | version: 1.1.4 306 | resolution: "color-name@npm:1.1.4" 307 | checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 308 | languageName: node 309 | linkType: hard 310 | 311 | "color-support@npm:^1.1.2": 312 | version: 1.1.3 313 | resolution: "color-support@npm:1.1.3" 314 | bin: 315 | color-support: bin.js 316 | checksum: 9b7356817670b9a13a26ca5af1c21615463b500783b739b7634a0c2047c16cef4b2865d7576875c31c3cddf9dd621fa19285e628f20198b233a5cfdda6d0793b 317 | languageName: node 318 | linkType: hard 319 | 320 | "concat-map@npm:0.0.1": 321 | version: 0.0.1 322 | resolution: "concat-map@npm:0.0.1" 323 | checksum: 902a9f5d8967a3e2faf138d5cb784b9979bad2e6db5357c5b21c568df4ebe62bcb15108af1b2253744844eb964fc023fbd9afbbbb6ddd0bcc204c6fb5b7bf3af 324 | languageName: node 325 | linkType: hard 326 | 327 | "console-control-strings@npm:^1.0.0, console-control-strings@npm:^1.1.0": 328 | version: 1.1.0 329 | resolution: "console-control-strings@npm:1.1.0" 330 | checksum: 8755d76787f94e6cf79ce4666f0c5519906d7f5b02d4b884cf41e11dcd759ed69c57da0670afd9236d229a46e0f9cf519db0cd829c6dca820bb5a5c3def584ed 331 | languageName: node 332 | linkType: hard 333 | 334 | "cross-spawn@npm:^6.0.5": 335 | version: 6.0.5 336 | resolution: "cross-spawn@npm:6.0.5" 337 | dependencies: 338 | nice-try: ^1.0.4 339 | path-key: ^2.0.1 340 | semver: ^5.5.0 341 | shebang-command: ^1.2.0 342 | which: ^1.2.9 343 | checksum: f893bb0d96cd3d5751d04e67145bdddf25f99449531a72e82dcbbd42796bbc8268c1076c6b3ea51d4d455839902804b94bc45dfb37ecbb32ea8e54a6741c3ab9 344 | languageName: node 345 | linkType: hard 346 | 347 | "debug@npm:4": 348 | version: 4.3.3 349 | resolution: "debug@npm:4.3.3" 350 | dependencies: 351 | ms: 2.1.2 352 | peerDependenciesMeta: 353 | supports-color: 354 | optional: true 355 | checksum: 14472d56fe4a94dbcfaa6dbed2dd3849f1d72ba78104a1a328047bb564643ca49df0224c3a17fa63533fd11dd3d4c8636cd861191232a2c6735af00cc2d4de16 356 | languageName: node 357 | linkType: hard 358 | 359 | "define-properties@npm:^1.1.3": 360 | version: 1.1.3 361 | resolution: "define-properties@npm:1.1.3" 362 | dependencies: 363 | object-keys: ^1.0.12 364 | checksum: da80dba55d0cd76a5a7ab71ef6ea0ebcb7b941f803793e4e0257b384cb772038faa0c31659d244e82c4342edef841c1a1212580006a05a5068ee48223d787317 365 | languageName: node 366 | linkType: hard 367 | 368 | "delegates@npm:^1.0.0": 369 | version: 1.0.0 370 | resolution: "delegates@npm:1.0.0" 371 | checksum: a51744d9b53c164ba9c0492471a1a2ffa0b6727451bdc89e31627fdf4adda9d51277cfcbfb20f0a6f08ccb3c436f341df3e92631a3440226d93a8971724771fd 372 | languageName: node 373 | linkType: hard 374 | 375 | "detect-libc@npm:^1.0.3": 376 | version: 1.0.3 377 | resolution: "detect-libc@npm:1.0.3" 378 | bin: 379 | detect-libc: ./bin/detect-libc.js 380 | checksum: daaaed925ffa7889bd91d56e9624e6c8033911bb60f3a50a74a87500680652969dbaab9526d1e200a4c94acf80fc862a22131841145a0a8482d60a99c24f4a3e 381 | languageName: node 382 | linkType: hard 383 | 384 | "emoji-regex@npm:^8.0.0": 385 | version: 8.0.0 386 | resolution: "emoji-regex@npm:8.0.0" 387 | checksum: d4c5c39d5a9868b5fa152f00cada8a936868fd3367f33f71be515ecee4c803132d11b31a6222b2571b1e5f7e13890156a94880345594d0ce7e3c9895f560f192 388 | languageName: node 389 | linkType: hard 390 | 391 | "error-ex@npm:^1.3.1": 392 | version: 1.3.2 393 | resolution: "error-ex@npm:1.3.2" 394 | dependencies: 395 | is-arrayish: ^0.2.1 396 | checksum: c1c2b8b65f9c91b0f9d75f0debaa7ec5b35c266c2cac5de412c1a6de86d4cbae04ae44e510378cb14d032d0645a36925d0186f8bb7367bcc629db256b743a001 397 | languageName: node 398 | linkType: hard 399 | 400 | "es-abstract@npm:^1.19.1": 401 | version: 1.19.1 402 | resolution: "es-abstract@npm:1.19.1" 403 | dependencies: 404 | call-bind: ^1.0.2 405 | es-to-primitive: ^1.2.1 406 | function-bind: ^1.1.1 407 | get-intrinsic: ^1.1.1 408 | get-symbol-description: ^1.0.0 409 | has: ^1.0.3 410 | has-symbols: ^1.0.2 411 | internal-slot: ^1.0.3 412 | is-callable: ^1.2.4 413 | is-negative-zero: ^2.0.1 414 | is-regex: ^1.1.4 415 | is-shared-array-buffer: ^1.0.1 416 | is-string: ^1.0.7 417 | is-weakref: ^1.0.1 418 | object-inspect: ^1.11.0 419 | object-keys: ^1.1.1 420 | object.assign: ^4.1.2 421 | string.prototype.trimend: ^1.0.4 422 | string.prototype.trimstart: ^1.0.4 423 | unbox-primitive: ^1.0.1 424 | checksum: b6be8410672c5364db3fb01eb786e30c7b4bb32b4af63d381c08840f4382c4a168e7855cd338bf59d4f1a1a1138f4d748d1fd40ec65aaa071876f9e9fbfed949 425 | languageName: node 426 | linkType: hard 427 | 428 | "es-to-primitive@npm:^1.2.1": 429 | version: 1.2.1 430 | resolution: "es-to-primitive@npm:1.2.1" 431 | dependencies: 432 | is-callable: ^1.1.4 433 | is-date-object: ^1.0.1 434 | is-symbol: ^1.0.2 435 | checksum: 4ead6671a2c1402619bdd77f3503991232ca15e17e46222b0a41a5d81aebc8740a77822f5b3c965008e631153e9ef0580540007744521e72de8e33599fca2eed 436 | languageName: node 437 | linkType: hard 438 | 439 | "escalade@npm:^3.1.1": 440 | version: 3.1.1 441 | resolution: "escalade@npm:3.1.1" 442 | checksum: a3e2a99f07acb74b3ad4989c48ca0c3140f69f923e56d0cba0526240ee470b91010f9d39001f2a4a313841d237ede70a729e92125191ba5d21e74b106800b133 443 | languageName: node 444 | linkType: hard 445 | 446 | "escape-string-regexp@npm:^1.0.5": 447 | version: 1.0.5 448 | resolution: "escape-string-regexp@npm:1.0.5" 449 | checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 450 | languageName: node 451 | linkType: hard 452 | 453 | "fs-minipass@npm:^2.0.0": 454 | version: 2.1.0 455 | resolution: "fs-minipass@npm:2.1.0" 456 | dependencies: 457 | minipass: ^3.0.0 458 | checksum: 1b8d128dae2ac6cc94230cc5ead341ba3e0efaef82dab46a33d171c044caaa6ca001364178d42069b2809c35a1c3c35079a32107c770e9ffab3901b59af8c8b1 459 | languageName: node 460 | linkType: hard 461 | 462 | "fs.realpath@npm:^1.0.0": 463 | version: 1.0.0 464 | resolution: "fs.realpath@npm:1.0.0" 465 | checksum: 99ddea01a7e75aa276c250a04eedeffe5662bce66c65c07164ad6264f9de18fb21be9433ead460e54cff20e31721c811f4fb5d70591799df5f85dce6d6746fd0 466 | languageName: node 467 | linkType: hard 468 | 469 | "function-bind@npm:^1.1.1": 470 | version: 1.1.1 471 | resolution: "function-bind@npm:1.1.1" 472 | checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a 473 | languageName: node 474 | linkType: hard 475 | 476 | "gauge@npm:^3.0.0": 477 | version: 3.0.2 478 | resolution: "gauge@npm:3.0.2" 479 | dependencies: 480 | aproba: ^1.0.3 || ^2.0.0 481 | color-support: ^1.1.2 482 | console-control-strings: ^1.0.0 483 | has-unicode: ^2.0.1 484 | object-assign: ^4.1.1 485 | signal-exit: ^3.0.0 486 | string-width: ^4.2.3 487 | strip-ansi: ^6.0.1 488 | wide-align: ^1.1.2 489 | checksum: 81296c00c7410cdd48f997800155fbead4f32e4f82109be0719c63edc8560e6579946cc8abd04205297640691ec26d21b578837fd13a4e96288ab4b40b1dc3e9 490 | languageName: node 491 | linkType: hard 492 | 493 | "gen-esm-wrapper@npm:^1.1.3": 494 | version: 1.1.3 495 | resolution: "gen-esm-wrapper@npm:1.1.3" 496 | dependencies: 497 | is-valid-identifier: ^2.0.2 498 | bin: 499 | gen-esm-wrapper: gen-esm-wrapper.js 500 | checksum: 600abe05141d3a3d71af3bd65a1967c7fd09bd7c60d487dca5c30b2af0f58b40580990d34cfa3ac1dffd78463d895912a100bac4ea6e8cb2ee4461bbafa67011 501 | languageName: node 502 | linkType: hard 503 | 504 | "get-caller-file@npm:^2.0.5": 505 | version: 2.0.5 506 | resolution: "get-caller-file@npm:2.0.5" 507 | checksum: b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 508 | languageName: node 509 | linkType: hard 510 | 511 | "get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1": 512 | version: 1.1.1 513 | resolution: "get-intrinsic@npm:1.1.1" 514 | dependencies: 515 | function-bind: ^1.1.1 516 | has: ^1.0.3 517 | has-symbols: ^1.0.1 518 | checksum: a9fe2ca8fa3f07f9b0d30fb202bcd01f3d9b9b6b732452e79c48e79f7d6d8d003af3f9e38514250e3553fdc83c61650851cb6870832ac89deaaceb08e3721a17 519 | languageName: node 520 | linkType: hard 521 | 522 | "get-symbol-description@npm:^1.0.0": 523 | version: 1.0.0 524 | resolution: "get-symbol-description@npm:1.0.0" 525 | dependencies: 526 | call-bind: ^1.0.2 527 | get-intrinsic: ^1.1.1 528 | checksum: 9ceff8fe968f9270a37a1f73bf3f1f7bda69ca80f4f80850670e0e7b9444ff99323f7ac52f96567f8b5f5fbe7ac717a0d81d3407c7313e82810c6199446a5247 529 | languageName: node 530 | linkType: hard 531 | 532 | "glob@npm:^7.1.3": 533 | version: 7.2.0 534 | resolution: "glob@npm:7.2.0" 535 | dependencies: 536 | fs.realpath: ^1.0.0 537 | inflight: ^1.0.4 538 | inherits: 2 539 | minimatch: ^3.0.4 540 | once: ^1.3.0 541 | path-is-absolute: ^1.0.0 542 | checksum: 78a8ea942331f08ed2e055cb5b9e40fe6f46f579d7fd3d694f3412fe5db23223d29b7fee1575440202e9a7ff9a72ab106a39fee39934c7bedafe5e5f8ae20134 543 | languageName: node 544 | linkType: hard 545 | 546 | "google-protobuf@npm:3.15.8": 547 | version: 3.15.8 548 | resolution: "google-protobuf@npm:3.15.8" 549 | checksum: f95f4d8203e94a6cf1983c8ad3b93ebe5e2b7408a39b5925332cce82e4a261cf9308a01458cd0887b78ccae885afcdff8e7a96da7c54c34baada79a84476f7fb 550 | languageName: node 551 | linkType: hard 552 | 553 | "google-protobuf@npm:^3.19.4": 554 | version: 3.19.4 555 | resolution: "google-protobuf@npm:3.19.4" 556 | checksum: c0ebc0afbb635271b54db933be74441429e0df095347d0145ae7036377a2cc6fc402ed015855ebc1809c7cedfde3246344ad28a98eac1e6a21800c7b572b2caf 557 | languageName: node 558 | linkType: hard 559 | 560 | "graceful-fs@npm:^4.1.2": 561 | version: 4.2.9 562 | resolution: "graceful-fs@npm:4.2.9" 563 | checksum: 68ea4e07ff2c041ada184f9278b830375f8e0b75154e3f080af6b70f66172fabb4108d19b3863a96b53fc068a310b9b6493d86d1291acc5f3861eb4b79d26ad6 564 | languageName: node 565 | linkType: hard 566 | 567 | "grpc-tools@npm:^1.10.0": 568 | version: 1.11.2 569 | resolution: "grpc-tools@npm:1.11.2" 570 | dependencies: 571 | "@mapbox/node-pre-gyp": ^1.0.5 572 | bin: 573 | grpc_tools_node_protoc: bin/protoc.js 574 | grpc_tools_node_protoc_plugin: bin/protoc_plugin.js 575 | checksum: 7df0778edadee09b982f31725f5170ec3679c40213e8c618ee5f5e9ee1062382798b45f2dacac1e63d5012cd2714c5e2904265a7ced64e1736147a17fd111960 576 | languageName: node 577 | linkType: hard 578 | 579 | "grpc_tools_node_protoc_ts@npm:^5.0.1": 580 | version: 5.3.2 581 | resolution: "grpc_tools_node_protoc_ts@npm:5.3.2" 582 | dependencies: 583 | google-protobuf: 3.15.8 584 | handlebars: 4.7.7 585 | bin: 586 | protoc-gen-ts: bin/protoc-gen-ts 587 | checksum: 5515c7877d4e297fc1c7800e5e8ee8c867d71af5fbfca1ebc500e681579fcb88c38aa396343d2dfc7fe8c7bdd0e3e550289cad1dce94d004c830c2103be3ff61 588 | languageName: node 589 | linkType: hard 590 | 591 | "handlebars@npm:4.7.7": 592 | version: 4.7.7 593 | resolution: "handlebars@npm:4.7.7" 594 | dependencies: 595 | minimist: ^1.2.5 596 | neo-async: ^2.6.0 597 | source-map: ^0.6.1 598 | uglify-js: ^3.1.4 599 | wordwrap: ^1.0.0 600 | dependenciesMeta: 601 | uglify-js: 602 | optional: true 603 | bin: 604 | handlebars: bin/handlebars 605 | checksum: 1e79a43f5e18d15742977cb987923eab3e2a8f44f2d9d340982bcb69e1735ed049226e534d7c1074eaddaf37e4fb4f471a8adb71cddd5bc8cf3f894241df5cee 606 | languageName: node 607 | linkType: hard 608 | 609 | "has-bigints@npm:^1.0.1": 610 | version: 1.0.1 611 | resolution: "has-bigints@npm:1.0.1" 612 | checksum: 44ab55868174470065d2e0f8f6def1c990d12b82162a8803c679699fa8a39f966e336f2a33c185092fe8aea7e8bf2e85f1c26add5f29d98f2318bd270096b183 613 | languageName: node 614 | linkType: hard 615 | 616 | "has-flag@npm:^3.0.0": 617 | version: 3.0.0 618 | resolution: "has-flag@npm:3.0.0" 619 | checksum: 4a15638b454bf086c8148979aae044dd6e39d63904cd452d970374fa6a87623423da485dfb814e7be882e05c096a7ccf1ebd48e7e7501d0208d8384ff4dea73b 620 | languageName: node 621 | linkType: hard 622 | 623 | "has-symbols@npm:^1.0.1, has-symbols@npm:^1.0.2": 624 | version: 1.0.2 625 | resolution: "has-symbols@npm:1.0.2" 626 | checksum: 2309c426071731be792b5be43b3da6fb4ed7cbe8a9a6bcfca1862587709f01b33d575ce8f5c264c1eaad09fca2f9a8208c0a2be156232629daa2dd0c0740976b 627 | languageName: node 628 | linkType: hard 629 | 630 | "has-tostringtag@npm:^1.0.0": 631 | version: 1.0.0 632 | resolution: "has-tostringtag@npm:1.0.0" 633 | dependencies: 634 | has-symbols: ^1.0.2 635 | checksum: cc12eb28cb6ae22369ebaad3a8ab0799ed61270991be88f208d508076a1e99abe4198c965935ce85ea90b60c94ddda73693b0920b58e7ead048b4a391b502c1c 636 | languageName: node 637 | linkType: hard 638 | 639 | "has-unicode@npm:^2.0.1": 640 | version: 2.0.1 641 | resolution: "has-unicode@npm:2.0.1" 642 | checksum: 1eab07a7436512db0be40a710b29b5dc21fa04880b7f63c9980b706683127e3c1b57cb80ea96d47991bdae2dfe479604f6a1ba410106ee1046a41d1bd0814400 643 | languageName: node 644 | linkType: hard 645 | 646 | "has@npm:^1.0.3": 647 | version: 1.0.3 648 | resolution: "has@npm:1.0.3" 649 | dependencies: 650 | function-bind: ^1.1.1 651 | checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792 652 | languageName: node 653 | linkType: hard 654 | 655 | "hosted-git-info@npm:^2.1.4": 656 | version: 2.8.9 657 | resolution: "hosted-git-info@npm:2.8.9" 658 | checksum: c955394bdab888a1e9bb10eb33029e0f7ce5a2ac7b3f158099dc8c486c99e73809dca609f5694b223920ca2174db33d32b12f9a2a47141dc59607c29da5a62dd 659 | languageName: node 660 | linkType: hard 661 | 662 | "https-proxy-agent@npm:^5.0.0": 663 | version: 5.0.0 664 | resolution: "https-proxy-agent@npm:5.0.0" 665 | dependencies: 666 | agent-base: 6 667 | debug: 4 668 | checksum: 165bfb090bd26d47693597661298006841ab733d0c7383a8cb2f17373387a94c903a3ac687090aa739de05e379ab6f868bae84ab4eac288ad85c328cd1ec9e53 669 | languageName: node 670 | linkType: hard 671 | 672 | "inflight@npm:^1.0.4": 673 | version: 1.0.6 674 | resolution: "inflight@npm:1.0.6" 675 | dependencies: 676 | once: ^1.3.0 677 | wrappy: 1 678 | checksum: f4f76aa072ce19fae87ce1ef7d221e709afb59d445e05d47fba710e85470923a75de35bfae47da6de1b18afc3ce83d70facf44cfb0aff89f0a3f45c0a0244dfd 679 | languageName: node 680 | linkType: hard 681 | 682 | "inherits@npm:2, inherits@npm:^2.0.3": 683 | version: 2.0.4 684 | resolution: "inherits@npm:2.0.4" 685 | checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 686 | languageName: node 687 | linkType: hard 688 | 689 | "inherits@npm:2.0.1": 690 | version: 2.0.1 691 | resolution: "inherits@npm:2.0.1" 692 | checksum: 6536b9377296d4ce8ee89c5c543cb75030934e61af42dba98a428e7d026938c5985ea4d1e3b87743a5b834f40ed1187f89c2d7479e9d59e41d2d1051aefba07b 693 | languageName: node 694 | linkType: hard 695 | 696 | "internal-slot@npm:^1.0.3": 697 | version: 1.0.3 698 | resolution: "internal-slot@npm:1.0.3" 699 | dependencies: 700 | get-intrinsic: ^1.1.0 701 | has: ^1.0.3 702 | side-channel: ^1.0.4 703 | checksum: 1944f92e981e47aebc98a88ff0db579fd90543d937806104d0b96557b10c1f170c51fb777b97740a8b6ddeec585fca8c39ae99fd08a8e058dfc8ab70937238bf 704 | languageName: node 705 | linkType: hard 706 | 707 | "is-arrayish@npm:^0.2.1": 708 | version: 0.2.1 709 | resolution: "is-arrayish@npm:0.2.1" 710 | checksum: eef4417e3c10e60e2c810b6084942b3ead455af16c4509959a27e490e7aee87cfb3f38e01bbde92220b528a0ee1a18d52b787e1458ee86174d8c7f0e58cd488f 711 | languageName: node 712 | linkType: hard 713 | 714 | "is-bigint@npm:^1.0.1": 715 | version: 1.0.4 716 | resolution: "is-bigint@npm:1.0.4" 717 | dependencies: 718 | has-bigints: ^1.0.1 719 | checksum: c56edfe09b1154f8668e53ebe8252b6f185ee852a50f9b41e8d921cb2bed425652049fbe438723f6cb48a63ca1aa051e948e7e401e093477c99c84eba244f666 720 | languageName: node 721 | linkType: hard 722 | 723 | "is-boolean-object@npm:^1.1.0": 724 | version: 1.1.2 725 | resolution: "is-boolean-object@npm:1.1.2" 726 | dependencies: 727 | call-bind: ^1.0.2 728 | has-tostringtag: ^1.0.0 729 | checksum: c03b23dbaacadc18940defb12c1c0e3aaece7553ef58b162a0f6bba0c2a7e1551b59f365b91e00d2dbac0522392d576ef322628cb1d036a0fe51eb466db67222 730 | languageName: node 731 | linkType: hard 732 | 733 | "is-callable@npm:^1.1.4, is-callable@npm:^1.2.4": 734 | version: 1.2.4 735 | resolution: "is-callable@npm:1.2.4" 736 | checksum: 1a28d57dc435797dae04b173b65d6d1e77d4f16276e9eff973f994eadcfdc30a017e6a597f092752a083c1103cceb56c91e3dadc6692fedb9898dfaba701575f 737 | languageName: node 738 | linkType: hard 739 | 740 | "is-core-module@npm:^2.8.1": 741 | version: 2.8.1 742 | resolution: "is-core-module@npm:2.8.1" 743 | dependencies: 744 | has: ^1.0.3 745 | checksum: 418b7bc10768a73c41c7ef497e293719604007f88934a6ffc5f7c78702791b8528102fb4c9e56d006d69361549b3d9519440214a74aefc7e0b79e5e4411d377f 746 | languageName: node 747 | linkType: hard 748 | 749 | "is-date-object@npm:^1.0.1": 750 | version: 1.0.5 751 | resolution: "is-date-object@npm:1.0.5" 752 | dependencies: 753 | has-tostringtag: ^1.0.0 754 | checksum: baa9077cdf15eb7b58c79398604ca57379b2fc4cf9aa7a9b9e295278648f628c9b201400c01c5e0f7afae56507d741185730307cbe7cad3b9f90a77e5ee342fc 755 | languageName: node 756 | linkType: hard 757 | 758 | "is-fullwidth-code-point@npm:^3.0.0": 759 | version: 3.0.0 760 | resolution: "is-fullwidth-code-point@npm:3.0.0" 761 | checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 762 | languageName: node 763 | linkType: hard 764 | 765 | "is-negative-zero@npm:^2.0.1": 766 | version: 2.0.2 767 | resolution: "is-negative-zero@npm:2.0.2" 768 | checksum: f3232194c47a549da60c3d509c9a09be442507616b69454716692e37ae9f37c4dea264fb208ad0c9f3efd15a796a46b79df07c7e53c6227c32170608b809149a 769 | languageName: node 770 | linkType: hard 771 | 772 | "is-number-object@npm:^1.0.4": 773 | version: 1.0.6 774 | resolution: "is-number-object@npm:1.0.6" 775 | dependencies: 776 | has-tostringtag: ^1.0.0 777 | checksum: c697704e8fc2027fc41cb81d29805de4e8b6dc9c3efee93741dbf126a8ecc8443fef85adbc581415ae7e55d325e51d0a942324ae35c829131748cce39cba55f3 778 | languageName: node 779 | linkType: hard 780 | 781 | "is-regex@npm:^1.1.4": 782 | version: 1.1.4 783 | resolution: "is-regex@npm:1.1.4" 784 | dependencies: 785 | call-bind: ^1.0.2 786 | has-tostringtag: ^1.0.0 787 | checksum: 362399b33535bc8f386d96c45c9feb04cf7f8b41c182f54174c1a45c9abbbe5e31290bbad09a458583ff6bf3b2048672cdb1881b13289569a7c548370856a652 788 | languageName: node 789 | linkType: hard 790 | 791 | "is-shared-array-buffer@npm:^1.0.1": 792 | version: 1.0.1 793 | resolution: "is-shared-array-buffer@npm:1.0.1" 794 | checksum: 2ffb92533e64e2876e6cfe6906871d28400b6f1a53130fe652ec8007bc0e5044d05e7af8e31bdc992fbba520bd92938cfbeedd0f286be92f250c7c76191c4d90 795 | languageName: node 796 | linkType: hard 797 | 798 | "is-string@npm:^1.0.5, is-string@npm:^1.0.7": 799 | version: 1.0.7 800 | resolution: "is-string@npm:1.0.7" 801 | dependencies: 802 | has-tostringtag: ^1.0.0 803 | checksum: 323b3d04622f78d45077cf89aab783b2f49d24dc641aa89b5ad1a72114cfeff2585efc8c12ef42466dff32bde93d839ad321b26884cf75e5a7892a938b089989 804 | languageName: node 805 | linkType: hard 806 | 807 | "is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": 808 | version: 1.0.4 809 | resolution: "is-symbol@npm:1.0.4" 810 | dependencies: 811 | has-symbols: ^1.0.2 812 | checksum: 92805812ef590738d9de49d677cd17dfd486794773fb6fa0032d16452af46e9b91bb43ffe82c983570f015b37136f4b53b28b8523bfb10b0ece7a66c31a54510 813 | languageName: node 814 | linkType: hard 815 | 816 | "is-valid-identifier@npm:^2.0.2": 817 | version: 2.0.2 818 | resolution: "is-valid-identifier@npm:2.0.2" 819 | dependencies: 820 | assert: ^1.4.1 821 | checksum: 79e5237998621f09b76582d8ef6928eb4cc96e78795d317aa1ea260aa5d22d4dae3c5baa519414f8e9a4833ee948e3bf0bd98496802f492c30640d672b528117 822 | languageName: node 823 | linkType: hard 824 | 825 | "is-weakref@npm:^1.0.1": 826 | version: 1.0.2 827 | resolution: "is-weakref@npm:1.0.2" 828 | dependencies: 829 | call-bind: ^1.0.2 830 | checksum: 95bd9a57cdcb58c63b1c401c60a474b0f45b94719c30f548c891860f051bc2231575c290a6b420c6bc6e7ed99459d424c652bd5bf9a1d5259505dc35b4bf83de 831 | languageName: node 832 | linkType: hard 833 | 834 | "isexe@npm:^2.0.0": 835 | version: 2.0.0 836 | resolution: "isexe@npm:2.0.0" 837 | checksum: 26bf6c5480dda5161c820c5b5c751ae1e766c587b1f951ea3fcfc973bafb7831ae5b54a31a69bd670220e42e99ec154475025a468eae58ea262f813fdc8d1c62 838 | languageName: node 839 | linkType: hard 840 | 841 | "json-parse-better-errors@npm:^1.0.1": 842 | version: 1.0.2 843 | resolution: "json-parse-better-errors@npm:1.0.2" 844 | checksum: ff2b5ba2a70e88fd97a3cb28c1840144c5ce8fae9cbeeddba15afa333a5c407cf0e42300cd0a2885dbb055227fe68d405070faad941beeffbfde9cf3b2c78c5d 845 | languageName: node 846 | linkType: hard 847 | 848 | "load-json-file@npm:^4.0.0": 849 | version: 4.0.0 850 | resolution: "load-json-file@npm:4.0.0" 851 | dependencies: 852 | graceful-fs: ^4.1.2 853 | parse-json: ^4.0.0 854 | pify: ^3.0.0 855 | strip-bom: ^3.0.0 856 | checksum: 8f5d6d93ba64a9620445ee9bde4d98b1eac32cf6c8c2d20d44abfa41a6945e7969456ab5f1ca2fb06ee32e206c9769a20eec7002fe290de462e8c884b6b8b356 857 | languageName: node 858 | linkType: hard 859 | 860 | "lodash.camelcase@npm:^4.3.0": 861 | version: 4.3.0 862 | resolution: "lodash.camelcase@npm:4.3.0" 863 | checksum: cb9227612f71b83e42de93eccf1232feeb25e705bdb19ba26c04f91e885bfd3dd5c517c4a97137658190581d3493ea3973072ca010aab7e301046d90740393d1 864 | languageName: node 865 | linkType: hard 866 | 867 | "long@npm:^4.0.0": 868 | version: 4.0.0 869 | resolution: "long@npm:4.0.0" 870 | checksum: 16afbe8f749c7c849db1f4de4e2e6a31ac6e617cead3bdc4f9605cb703cd20e1e9fc1a7baba674ffcca57d660a6e5b53a9e236d7b25a295d3855cca79cc06744 871 | languageName: node 872 | linkType: hard 873 | 874 | "lru-cache@npm:^6.0.0": 875 | version: 6.0.0 876 | resolution: "lru-cache@npm:6.0.0" 877 | dependencies: 878 | yallist: ^4.0.0 879 | checksum: f97f499f898f23e4585742138a22f22526254fdba6d75d41a1c2526b3b6cc5747ef59c5612ba7375f42aca4f8461950e925ba08c991ead0651b4918b7c978297 880 | languageName: node 881 | linkType: hard 882 | 883 | "make-dir@npm:^3.1.0": 884 | version: 3.1.0 885 | resolution: "make-dir@npm:3.1.0" 886 | dependencies: 887 | semver: ^6.0.0 888 | checksum: 484200020ab5a1fdf12f393fe5f385fc8e4378824c940fba1729dcd198ae4ff24867bc7a5646331e50cead8abff5d9270c456314386e629acec6dff4b8016b78 889 | languageName: node 890 | linkType: hard 891 | 892 | "memorystream@npm:^0.3.1": 893 | version: 0.3.1 894 | resolution: "memorystream@npm:0.3.1" 895 | checksum: f18b42440d24d09516d01466c06adf797df7873f0d40aa7db02e5fb9ed83074e5e65412d0720901d7069363465f82dc4f8bcb44f0cde271567a61426ce6ca2e9 896 | languageName: node 897 | linkType: hard 898 | 899 | "minimatch@npm:^3.0.4": 900 | version: 3.1.2 901 | resolution: "minimatch@npm:3.1.2" 902 | dependencies: 903 | brace-expansion: ^1.1.7 904 | checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a 905 | languageName: node 906 | linkType: hard 907 | 908 | "minimist@npm:^1.2.5": 909 | version: 1.2.5 910 | resolution: "minimist@npm:1.2.5" 911 | checksum: 86706ce5b36c16bfc35c5fe3dbb01d5acdc9a22f2b6cc810b6680656a1d2c0e44a0159c9a3ba51fb072bb5c203e49e10b51dcd0eec39c481f4c42086719bae52 912 | languageName: node 913 | linkType: hard 914 | 915 | "minipass@npm:^3.0.0": 916 | version: 3.1.6 917 | resolution: "minipass@npm:3.1.6" 918 | dependencies: 919 | yallist: ^4.0.0 920 | checksum: 57a04041413a3531a65062452cb5175f93383ef245d6f4a2961d34386eb9aa8ac11ac7f16f791f5e8bbaf1dfb1ef01596870c88e8822215db57aa591a5bb0a77 921 | languageName: node 922 | linkType: hard 923 | 924 | "minizlib@npm:^2.1.1": 925 | version: 2.1.2 926 | resolution: "minizlib@npm:2.1.2" 927 | dependencies: 928 | minipass: ^3.0.0 929 | yallist: ^4.0.0 930 | checksum: f1fdeac0b07cf8f30fcf12f4b586795b97be856edea22b5e9072707be51fc95d41487faec3f265b42973a304fe3a64acd91a44a3826a963e37b37bafde0212c3 931 | languageName: node 932 | linkType: hard 933 | 934 | "mkdirp@npm:^1.0.3": 935 | version: 1.0.4 936 | resolution: "mkdirp@npm:1.0.4" 937 | bin: 938 | mkdirp: bin/cmd.js 939 | checksum: a96865108c6c3b1b8e1d5e9f11843de1e077e57737602de1b82030815f311be11f96f09cce59bd5b903d0b29834733e5313f9301e3ed6d6f6fba2eae0df4298f 940 | languageName: node 941 | linkType: hard 942 | 943 | "ms@npm:2.1.2": 944 | version: 2.1.2 945 | resolution: "ms@npm:2.1.2" 946 | checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f 947 | languageName: node 948 | linkType: hard 949 | 950 | "neo-async@npm:^2.6.0": 951 | version: 2.6.2 952 | resolution: "neo-async@npm:2.6.2" 953 | checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 954 | languageName: node 955 | linkType: hard 956 | 957 | "nice-try@npm:^1.0.4": 958 | version: 1.0.5 959 | resolution: "nice-try@npm:1.0.5" 960 | checksum: 0b4af3b5bb5d86c289f7a026303d192a7eb4417231fe47245c460baeabae7277bcd8fd9c728fb6bd62c30b3e15cd6620373e2cf33353b095d8b403d3e8a15aff 961 | languageName: node 962 | linkType: hard 963 | 964 | "node-fetch@npm:^2.6.5": 965 | version: 2.6.7 966 | resolution: "node-fetch@npm:2.6.7" 967 | dependencies: 968 | whatwg-url: ^5.0.0 969 | peerDependencies: 970 | encoding: ^0.1.0 971 | peerDependenciesMeta: 972 | encoding: 973 | optional: true 974 | checksum: 8d816ffd1ee22cab8301c7756ef04f3437f18dace86a1dae22cf81db8ef29c0bf6655f3215cb0cdb22b420b6fe141e64b26905e7f33f9377a7fa59135ea3e10b 975 | languageName: node 976 | linkType: hard 977 | 978 | "nopt@npm:^5.0.0": 979 | version: 5.0.0 980 | resolution: "nopt@npm:5.0.0" 981 | dependencies: 982 | abbrev: 1 983 | bin: 984 | nopt: bin/nopt.js 985 | checksum: d35fdec187269503843924e0114c0c6533fb54bbf1620d0f28b4b60ba01712d6687f62565c55cc20a504eff0fbe5c63e22340c3fad549ad40469ffb611b04f2f 986 | languageName: node 987 | linkType: hard 988 | 989 | "normalize-package-data@npm:^2.3.2": 990 | version: 2.5.0 991 | resolution: "normalize-package-data@npm:2.5.0" 992 | dependencies: 993 | hosted-git-info: ^2.1.4 994 | resolve: ^1.10.0 995 | semver: 2 || 3 || 4 || 5 996 | validate-npm-package-license: ^3.0.1 997 | checksum: 7999112efc35a6259bc22db460540cae06564aa65d0271e3bdfa86876d08b0e578b7b5b0028ee61b23f1cae9fc0e7847e4edc0948d3068a39a2a82853efc8499 998 | languageName: node 999 | linkType: hard 1000 | 1001 | "npm-run-all@npm:^4.1.5": 1002 | version: 4.1.5 1003 | resolution: "npm-run-all@npm:4.1.5" 1004 | dependencies: 1005 | ansi-styles: ^3.2.1 1006 | chalk: ^2.4.1 1007 | cross-spawn: ^6.0.5 1008 | memorystream: ^0.3.1 1009 | minimatch: ^3.0.4 1010 | pidtree: ^0.3.0 1011 | read-pkg: ^3.0.0 1012 | shell-quote: ^1.6.1 1013 | string.prototype.padend: ^3.0.0 1014 | bin: 1015 | npm-run-all: bin/npm-run-all/index.js 1016 | run-p: bin/run-p/index.js 1017 | run-s: bin/run-s/index.js 1018 | checksum: 373b72c6a36564da13c1642c1fd9bb4dcc756bce7a3648f883772f02661095319820834ff813762d2fee403e9b40c1cd27c8685807c107440f10eb19c006d4a0 1019 | languageName: node 1020 | linkType: hard 1021 | 1022 | "npmlog@npm:^5.0.1": 1023 | version: 5.0.1 1024 | resolution: "npmlog@npm:5.0.1" 1025 | dependencies: 1026 | are-we-there-yet: ^2.0.0 1027 | console-control-strings: ^1.1.0 1028 | gauge: ^3.0.0 1029 | set-blocking: ^2.0.0 1030 | checksum: 516b2663028761f062d13e8beb3f00069c5664925871a9b57989642ebe09f23ab02145bf3ab88da7866c4e112cafff72401f61a672c7c8a20edc585a7016ef5f 1031 | languageName: node 1032 | linkType: hard 1033 | 1034 | "object-assign@npm:^4.1.1": 1035 | version: 4.1.1 1036 | resolution: "object-assign@npm:4.1.1" 1037 | checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f 1038 | languageName: node 1039 | linkType: hard 1040 | 1041 | "object-inspect@npm:^1.11.0, object-inspect@npm:^1.9.0": 1042 | version: 1.12.0 1043 | resolution: "object-inspect@npm:1.12.0" 1044 | checksum: 2b36d4001a9c921c6b342e2965734519c9c58c355822243c3207fbf0aac271f8d44d30d2d570d450b2cc6f0f00b72bcdba515c37827d2560e5f22b1899a31cf4 1045 | languageName: node 1046 | linkType: hard 1047 | 1048 | "object-keys@npm:^1.0.12, object-keys@npm:^1.1.1": 1049 | version: 1.1.1 1050 | resolution: "object-keys@npm:1.1.1" 1051 | checksum: b363c5e7644b1e1b04aa507e88dcb8e3a2f52b6ffd0ea801e4c7a62d5aa559affe21c55a07fd4b1fd55fc03a33c610d73426664b20032405d7b92a1414c34d6a 1052 | languageName: node 1053 | linkType: hard 1054 | 1055 | "object.assign@npm:^4.1.2": 1056 | version: 4.1.2 1057 | resolution: "object.assign@npm:4.1.2" 1058 | dependencies: 1059 | call-bind: ^1.0.0 1060 | define-properties: ^1.1.3 1061 | has-symbols: ^1.0.1 1062 | object-keys: ^1.1.1 1063 | checksum: d621d832ed7b16ac74027adb87196804a500d80d9aca536fccb7ba48d33a7e9306a75f94c1d29cbfa324bc091bfc530bc24789568efdaee6a47fcfa298993814 1064 | languageName: node 1065 | linkType: hard 1066 | 1067 | "once@npm:^1.3.0": 1068 | version: 1.4.0 1069 | resolution: "once@npm:1.4.0" 1070 | dependencies: 1071 | wrappy: 1 1072 | checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 1073 | languageName: node 1074 | linkType: hard 1075 | 1076 | "parse-json@npm:^4.0.0": 1077 | version: 4.0.0 1078 | resolution: "parse-json@npm:4.0.0" 1079 | dependencies: 1080 | error-ex: ^1.3.1 1081 | json-parse-better-errors: ^1.0.1 1082 | checksum: 0fe227d410a61090c247e34fa210552b834613c006c2c64d9a05cfe9e89cf8b4246d1246b1a99524b53b313e9ac024438d0680f67e33eaed7e6f38db64cfe7b5 1083 | languageName: node 1084 | linkType: hard 1085 | 1086 | "path-is-absolute@npm:^1.0.0": 1087 | version: 1.0.1 1088 | resolution: "path-is-absolute@npm:1.0.1" 1089 | checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 1090 | languageName: node 1091 | linkType: hard 1092 | 1093 | "path-key@npm:^2.0.1": 1094 | version: 2.0.1 1095 | resolution: "path-key@npm:2.0.1" 1096 | checksum: f7ab0ad42fe3fb8c7f11d0c4f849871e28fbd8e1add65c370e422512fc5887097b9cf34d09c1747d45c942a8c1e26468d6356e2df3f740bf177ab8ca7301ebfd 1097 | languageName: node 1098 | linkType: hard 1099 | 1100 | "path-parse@npm:^1.0.7": 1101 | version: 1.0.7 1102 | resolution: "path-parse@npm:1.0.7" 1103 | checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a 1104 | languageName: node 1105 | linkType: hard 1106 | 1107 | "path-type@npm:^3.0.0": 1108 | version: 3.0.0 1109 | resolution: "path-type@npm:3.0.0" 1110 | dependencies: 1111 | pify: ^3.0.0 1112 | checksum: 735b35e256bad181f38fa021033b1c33cfbe62ead42bb2222b56c210e42938eecb272ae1949f3b6db4ac39597a61b44edd8384623ec4d79bfdc9a9c0f12537a6 1113 | languageName: node 1114 | linkType: hard 1115 | 1116 | "pidtree@npm:^0.3.0": 1117 | version: 0.3.1 1118 | resolution: "pidtree@npm:0.3.1" 1119 | bin: 1120 | pidtree: bin/pidtree.js 1121 | checksum: eb49025099f1af89a4696f7673351421f13420f3397b963c901fe23a1c9c2ff50f4750321970d4472c0ffbb065e4a6c3c27f75e226cc62284b19e21d32ce7012 1122 | languageName: node 1123 | linkType: hard 1124 | 1125 | "pify@npm:^3.0.0": 1126 | version: 3.0.0 1127 | resolution: "pify@npm:3.0.0" 1128 | checksum: 6cdcbc3567d5c412450c53261a3f10991665d660961e06605decf4544a61a97a54fefe70a68d5c37080ff9d6f4cf51444c90198d1ba9f9309a6c0d6e9f5c4fde 1129 | languageName: node 1130 | linkType: hard 1131 | 1132 | "protobufjs@npm:^6.10.0": 1133 | version: 6.11.2 1134 | resolution: "protobufjs@npm:6.11.2" 1135 | dependencies: 1136 | "@protobufjs/aspromise": ^1.1.2 1137 | "@protobufjs/base64": ^1.1.2 1138 | "@protobufjs/codegen": ^2.0.4 1139 | "@protobufjs/eventemitter": ^1.1.0 1140 | "@protobufjs/fetch": ^1.1.0 1141 | "@protobufjs/float": ^1.0.2 1142 | "@protobufjs/inquire": ^1.1.0 1143 | "@protobufjs/path": ^1.1.2 1144 | "@protobufjs/pool": ^1.1.0 1145 | "@protobufjs/utf8": ^1.1.0 1146 | "@types/long": ^4.0.1 1147 | "@types/node": ">=13.7.0" 1148 | long: ^4.0.0 1149 | bin: 1150 | pbjs: bin/pbjs 1151 | pbts: bin/pbts 1152 | checksum: 80e9d9610c3eb66f9eae4e44a1ae30381cedb721b7d5f635d781fe4c507e2c77bb7c879addcd1dda79733d3ae589d9e66fd18d42baf99b35df7382a0f9920795 1153 | languageName: node 1154 | linkType: hard 1155 | 1156 | "read-pkg@npm:^3.0.0": 1157 | version: 3.0.0 1158 | resolution: "read-pkg@npm:3.0.0" 1159 | dependencies: 1160 | load-json-file: ^4.0.0 1161 | normalize-package-data: ^2.3.2 1162 | path-type: ^3.0.0 1163 | checksum: 398903ebae6c7e9965419a1062924436cc0b6f516c42c4679a90290d2f87448ed8f977e7aa2dbba4aa1ac09248628c43e493ac25b2bc76640e946035200e34c6 1164 | languageName: node 1165 | linkType: hard 1166 | 1167 | "readable-stream@npm:^3.6.0": 1168 | version: 3.6.0 1169 | resolution: "readable-stream@npm:3.6.0" 1170 | dependencies: 1171 | inherits: ^2.0.3 1172 | string_decoder: ^1.1.1 1173 | util-deprecate: ^1.0.1 1174 | checksum: d4ea81502d3799439bb955a3a5d1d808592cf3133350ed352aeaa499647858b27b1c4013984900238b0873ec8d0d8defce72469fb7a83e61d53f5ad61cb80dc8 1175 | languageName: node 1176 | linkType: hard 1177 | 1178 | "require-directory@npm:^2.1.1": 1179 | version: 2.1.1 1180 | resolution: "require-directory@npm:2.1.1" 1181 | checksum: fb47e70bf0001fdeabdc0429d431863e9475e7e43ea5f94ad86503d918423c1543361cc5166d713eaa7029dd7a3d34775af04764bebff99ef413111a5af18c80 1182 | languageName: node 1183 | linkType: hard 1184 | 1185 | "resolve@npm:^1.10.0": 1186 | version: 1.22.0 1187 | resolution: "resolve@npm:1.22.0" 1188 | dependencies: 1189 | is-core-module: ^2.8.1 1190 | path-parse: ^1.0.7 1191 | supports-preserve-symlinks-flag: ^1.0.0 1192 | bin: 1193 | resolve: bin/resolve 1194 | checksum: a2d14cc437b3a23996f8c7367eee5c7cf8149c586b07ca2ae00e96581ce59455555a1190be9aa92154785cf9f2042646c200d0e00e0bbd2b8a995a93a0ed3e4e 1195 | languageName: node 1196 | linkType: hard 1197 | 1198 | "resolve@patch:resolve@^1.10.0#~builtin": 1199 | version: 1.22.0 1200 | resolution: "resolve@patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=c3c19d" 1201 | dependencies: 1202 | is-core-module: ^2.8.1 1203 | path-parse: ^1.0.7 1204 | supports-preserve-symlinks-flag: ^1.0.0 1205 | bin: 1206 | resolve: bin/resolve 1207 | checksum: c79ecaea36c872ee4a79e3db0d3d4160b593f2ca16e031d8283735acd01715a203607e9ded3f91f68899c2937fa0d49390cddbe0fb2852629212f3cda283f4a7 1208 | languageName: node 1209 | linkType: hard 1210 | 1211 | "rimraf@npm:^3.0.2": 1212 | version: 3.0.2 1213 | resolution: "rimraf@npm:3.0.2" 1214 | dependencies: 1215 | glob: ^7.1.3 1216 | bin: 1217 | rimraf: bin.js 1218 | checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0 1219 | languageName: node 1220 | linkType: hard 1221 | 1222 | "rxjs@npm:*": 1223 | version: 7.5.7 1224 | resolution: "rxjs@npm:7.5.7" 1225 | dependencies: 1226 | tslib: ^2.1.0 1227 | checksum: edabcdb73b0f7e0f5f6e05c2077aff8c52222ac939069729704357d6406438acca831c24210db320aba269e86dbe1a400f3769c89101791885121a342fb15d9c 1228 | languageName: node 1229 | linkType: hard 1230 | 1231 | "safe-buffer@npm:~5.2.0": 1232 | version: 5.2.1 1233 | resolution: "safe-buffer@npm:5.2.1" 1234 | checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 1235 | languageName: node 1236 | linkType: hard 1237 | 1238 | "semver@npm:2 || 3 || 4 || 5, semver@npm:^5.5.0": 1239 | version: 5.7.1 1240 | resolution: "semver@npm:5.7.1" 1241 | bin: 1242 | semver: ./bin/semver 1243 | checksum: 57fd0acfd0bac382ee87cd52cd0aaa5af086a7dc8d60379dfe65fea491fb2489b6016400813930ecd61fd0952dae75c115287a1b16c234b1550887117744dfaf 1244 | languageName: node 1245 | linkType: hard 1246 | 1247 | "semver@npm:^6.0.0": 1248 | version: 6.3.0 1249 | resolution: "semver@npm:6.3.0" 1250 | bin: 1251 | semver: ./bin/semver.js 1252 | checksum: 1b26ecf6db9e8292dd90df4e781d91875c0dcc1b1909e70f5d12959a23c7eebb8f01ea581c00783bbee72ceeaad9505797c381756326073850dc36ed284b21b9 1253 | languageName: node 1254 | linkType: hard 1255 | 1256 | "semver@npm:^7.3.5": 1257 | version: 7.3.5 1258 | resolution: "semver@npm:7.3.5" 1259 | dependencies: 1260 | lru-cache: ^6.0.0 1261 | bin: 1262 | semver: bin/semver.js 1263 | checksum: 5eafe6102bea2a7439897c1856362e31cc348ccf96efd455c8b5bc2c61e6f7e7b8250dc26b8828c1d76a56f818a7ee907a36ae9fb37a599d3d24609207001d60 1264 | languageName: node 1265 | linkType: hard 1266 | 1267 | "set-blocking@npm:^2.0.0": 1268 | version: 2.0.0 1269 | resolution: "set-blocking@npm:2.0.0" 1270 | checksum: 6e65a05f7cf7ebdf8b7c75b101e18c0b7e3dff4940d480efed8aad3a36a4005140b660fa1d804cb8bce911cac290441dc728084a30504d3516ac2ff7ad607b02 1271 | languageName: node 1272 | linkType: hard 1273 | 1274 | "shebang-command@npm:^1.2.0": 1275 | version: 1.2.0 1276 | resolution: "shebang-command@npm:1.2.0" 1277 | dependencies: 1278 | shebang-regex: ^1.0.0 1279 | checksum: 9eed1750301e622961ba5d588af2212505e96770ec376a37ab678f965795e995ade7ed44910f5d3d3cb5e10165a1847f52d3348c64e146b8be922f7707958908 1280 | languageName: node 1281 | linkType: hard 1282 | 1283 | "shebang-regex@npm:^1.0.0": 1284 | version: 1.0.0 1285 | resolution: "shebang-regex@npm:1.0.0" 1286 | checksum: 404c5a752cd40f94591dfd9346da40a735a05139dac890ffc229afba610854d8799aaa52f87f7e0c94c5007f2c6af55bdcaeb584b56691926c5eaf41dc8f1372 1287 | languageName: node 1288 | linkType: hard 1289 | 1290 | "shell-quote@npm:^1.6.1": 1291 | version: 1.7.3 1292 | resolution: "shell-quote@npm:1.7.3" 1293 | checksum: aca58e73a3a5d933d02e0bdddedc53ee14f7c2ec264f97ac915b9d4482d077a38e422aa664631d60a672cd3cdb4054eb2e6c0303f54882453dacb6483e482d34 1294 | languageName: node 1295 | linkType: hard 1296 | 1297 | "side-channel@npm:^1.0.4": 1298 | version: 1.0.4 1299 | resolution: "side-channel@npm:1.0.4" 1300 | dependencies: 1301 | call-bind: ^1.0.0 1302 | get-intrinsic: ^1.0.2 1303 | object-inspect: ^1.9.0 1304 | checksum: 351e41b947079c10bd0858364f32bb3a7379514c399edb64ab3dce683933483fc63fb5e4efe0a15a2e8a7e3c436b6a91736ddb8d8c6591b0460a24bb4a1ee245 1305 | languageName: node 1306 | linkType: hard 1307 | 1308 | "signal-exit@npm:^3.0.0": 1309 | version: 3.0.7 1310 | resolution: "signal-exit@npm:3.0.7" 1311 | checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 1312 | languageName: node 1313 | linkType: hard 1314 | 1315 | "source-map@npm:^0.6.1": 1316 | version: 0.6.1 1317 | resolution: "source-map@npm:0.6.1" 1318 | checksum: 59ce8640cf3f3124f64ac289012c2b8bd377c238e316fb323ea22fbfe83da07d81e000071d7242cad7a23cd91c7de98e4df8830ec3f133cb6133a5f6e9f67bc2 1319 | languageName: node 1320 | linkType: hard 1321 | 1322 | "spdx-correct@npm:^3.0.0": 1323 | version: 3.1.1 1324 | resolution: "spdx-correct@npm:3.1.1" 1325 | dependencies: 1326 | spdx-expression-parse: ^3.0.0 1327 | spdx-license-ids: ^3.0.0 1328 | checksum: 77ce438344a34f9930feffa61be0eddcda5b55fc592906ef75621d4b52c07400a97084d8701557b13f7d2aae0cb64f808431f469e566ef3fe0a3a131dcb775a6 1329 | languageName: node 1330 | linkType: hard 1331 | 1332 | "spdx-exceptions@npm:^2.1.0": 1333 | version: 2.3.0 1334 | resolution: "spdx-exceptions@npm:2.3.0" 1335 | checksum: cb69a26fa3b46305637123cd37c85f75610e8c477b6476fa7354eb67c08128d159f1d36715f19be6f9daf4b680337deb8c65acdcae7f2608ba51931540687ac0 1336 | languageName: node 1337 | linkType: hard 1338 | 1339 | "spdx-expression-parse@npm:^3.0.0": 1340 | version: 3.0.1 1341 | resolution: "spdx-expression-parse@npm:3.0.1" 1342 | dependencies: 1343 | spdx-exceptions: ^2.1.0 1344 | spdx-license-ids: ^3.0.0 1345 | checksum: a1c6e104a2cbada7a593eaa9f430bd5e148ef5290d4c0409899855ce8b1c39652bcc88a725259491a82601159d6dc790bedefc9016c7472f7de8de7361f8ccde 1346 | languageName: node 1347 | linkType: hard 1348 | 1349 | "spdx-license-ids@npm:^3.0.0": 1350 | version: 3.0.11 1351 | resolution: "spdx-license-ids@npm:3.0.11" 1352 | checksum: 1da1acb090257773e60b022094050e810ae9fec874dc1461f65dc0400cd42dd830ab2df6e64fb49c2db3dce386dd0362110780e1b154db7c0bb413488836aaeb 1353 | languageName: node 1354 | linkType: hard 1355 | 1356 | "string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": 1357 | version: 4.2.3 1358 | resolution: "string-width@npm:4.2.3" 1359 | dependencies: 1360 | emoji-regex: ^8.0.0 1361 | is-fullwidth-code-point: ^3.0.0 1362 | strip-ansi: ^6.0.1 1363 | checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb 1364 | languageName: node 1365 | linkType: hard 1366 | 1367 | "string.prototype.padend@npm:^3.0.0": 1368 | version: 3.1.3 1369 | resolution: "string.prototype.padend@npm:3.1.3" 1370 | dependencies: 1371 | call-bind: ^1.0.2 1372 | define-properties: ^1.1.3 1373 | es-abstract: ^1.19.1 1374 | checksum: ef9ee0542c17975629bc6d21497e8faaa142d873e9f07fb65de2a955df402a1eac45cbed375045a759501e9d4ef80e589e11f0e12103c20df0770e47f6b59bc7 1375 | languageName: node 1376 | linkType: hard 1377 | 1378 | "string.prototype.trimend@npm:^1.0.4": 1379 | version: 1.0.4 1380 | resolution: "string.prototype.trimend@npm:1.0.4" 1381 | dependencies: 1382 | call-bind: ^1.0.2 1383 | define-properties: ^1.1.3 1384 | checksum: 17e5aa45c3983f582693161f972c1c1fa4bbbdf22e70e582b00c91b6575f01680dc34e83005b98e31abe4d5d29e0b21fcc24690239c106c7b2315aade6a898ac 1385 | languageName: node 1386 | linkType: hard 1387 | 1388 | "string.prototype.trimstart@npm:^1.0.4": 1389 | version: 1.0.4 1390 | resolution: "string.prototype.trimstart@npm:1.0.4" 1391 | dependencies: 1392 | call-bind: ^1.0.2 1393 | define-properties: ^1.1.3 1394 | checksum: 3fb06818d3cccac5fa3f5f9873d984794ca0e9f6616fae6fcc745885d9efed4e17fe15f832515d9af5e16c279857fdbffdfc489ca4ed577811b017721b30302f 1395 | languageName: node 1396 | linkType: hard 1397 | 1398 | "string_decoder@npm:^1.1.1": 1399 | version: 1.3.0 1400 | resolution: "string_decoder@npm:1.3.0" 1401 | dependencies: 1402 | safe-buffer: ~5.2.0 1403 | checksum: 8417646695a66e73aefc4420eb3b84cc9ffd89572861fe004e6aeb13c7bc00e2f616247505d2dbbef24247c372f70268f594af7126f43548565c68c117bdeb56 1404 | languageName: node 1405 | linkType: hard 1406 | 1407 | "strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": 1408 | version: 6.0.1 1409 | resolution: "strip-ansi@npm:6.0.1" 1410 | dependencies: 1411 | ansi-regex: ^5.0.1 1412 | checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c 1413 | languageName: node 1414 | linkType: hard 1415 | 1416 | "strip-bom@npm:^3.0.0": 1417 | version: 3.0.0 1418 | resolution: "strip-bom@npm:3.0.0" 1419 | checksum: 8d50ff27b7ebe5ecc78f1fe1e00fcdff7af014e73cf724b46fb81ef889eeb1015fc5184b64e81a2efe002180f3ba431bdd77e300da5c6685d702780fbf0c8d5b 1420 | languageName: node 1421 | linkType: hard 1422 | 1423 | "supports-color@npm:^5.3.0": 1424 | version: 5.5.0 1425 | resolution: "supports-color@npm:5.5.0" 1426 | dependencies: 1427 | has-flag: ^3.0.0 1428 | checksum: 95f6f4ba5afdf92f495b5a912d4abee8dcba766ae719b975c56c084f5004845f6f5a5f7769f52d53f40e21952a6d87411bafe34af4a01e65f9926002e38e1dac 1429 | languageName: node 1430 | linkType: hard 1431 | 1432 | "supports-preserve-symlinks-flag@npm:^1.0.0": 1433 | version: 1.0.0 1434 | resolution: "supports-preserve-symlinks-flag@npm:1.0.0" 1435 | checksum: 53b1e247e68e05db7b3808b99b892bd36fb096e6fba213a06da7fab22045e97597db425c724f2bbd6c99a3c295e1e73f3e4de78592289f38431049e1277ca0ae 1436 | languageName: node 1437 | linkType: hard 1438 | 1439 | "tar@npm:^6.1.11": 1440 | version: 6.1.11 1441 | resolution: "tar@npm:6.1.11" 1442 | dependencies: 1443 | chownr: ^2.0.0 1444 | fs-minipass: ^2.0.0 1445 | minipass: ^3.0.0 1446 | minizlib: ^2.1.1 1447 | mkdirp: ^1.0.3 1448 | yallist: ^4.0.0 1449 | checksum: a04c07bb9e2d8f46776517d4618f2406fb977a74d914ad98b264fc3db0fe8224da5bec11e5f8902c5b9bcb8ace22d95fbe3c7b36b8593b7dfc8391a25898f32f 1450 | languageName: node 1451 | linkType: hard 1452 | 1453 | "tr46@npm:~0.0.3": 1454 | version: 0.0.3 1455 | resolution: "tr46@npm:0.0.3" 1456 | checksum: 726321c5eaf41b5002e17ffbd1fb7245999a073e8979085dacd47c4b4e8068ff5777142fc6726d6ca1fd2ff16921b48788b87225cbc57c72636f6efa8efbffe3 1457 | languageName: node 1458 | linkType: hard 1459 | 1460 | "tslib@npm:^2.1.0": 1461 | version: 2.4.1 1462 | resolution: "tslib@npm:2.4.1" 1463 | checksum: 19480d6e0313292bd6505d4efe096a6b31c70e21cf08b5febf4da62e95c265c8f571f7b36fcc3d1a17e068032f59c269fab3459d6cd3ed6949eafecf64315fca 1464 | languageName: node 1465 | linkType: hard 1466 | 1467 | "typed-emitter@npm:^2.1.0": 1468 | version: 2.1.0 1469 | resolution: "typed-emitter@npm:2.1.0" 1470 | dependencies: 1471 | rxjs: "*" 1472 | dependenciesMeta: 1473 | rxjs: 1474 | optional: true 1475 | checksum: 95821a9e05784b972cc9d152891fd12a56cb4b1a7c57e768c02bea6a8984da7aff8f19404a7b69eea11fae2a3b6c0c510a4c510f575f50162c759ae9059f2520 1476 | languageName: node 1477 | linkType: hard 1478 | 1479 | "typescript@npm:^4.5.5": 1480 | version: 4.5.5 1481 | resolution: "typescript@npm:4.5.5" 1482 | bin: 1483 | tsc: bin/tsc 1484 | tsserver: bin/tsserver 1485 | checksum: 506f4c919dc8aeaafa92068c997f1d213b9df4d9756d0fae1a1e7ab66b585ab3498050e236113a1c9e57ee08c21ec6814ca7a7f61378c058d79af50a4b1f5a5e 1486 | languageName: node 1487 | linkType: hard 1488 | 1489 | "typescript@patch:typescript@^4.5.5#~builtin": 1490 | version: 4.5.5 1491 | resolution: "typescript@patch:typescript@npm%3A4.5.5#~builtin::version=4.5.5&hash=bcec9a" 1492 | bin: 1493 | tsc: bin/tsc 1494 | tsserver: bin/tsserver 1495 | checksum: 858c61fa63f7274ca4aaaffeced854d550bf416cff6e558c4884041b3311fb662f476f167cf5c9f8680c607239797e26a2ee0bcc6467fbc05bfcb218e1c6c671 1496 | languageName: node 1497 | linkType: hard 1498 | 1499 | "uglify-js@npm:^3.1.4": 1500 | version: 3.15.1 1501 | resolution: "uglify-js@npm:3.15.1" 1502 | bin: 1503 | uglifyjs: bin/uglifyjs 1504 | checksum: cf88574ec8af4d69368142a3f9fb83ac11b1344a117dff08890fcf99ed12c782c810f02e71a0c2a7e8666ea6225894f1c171cbd90e1a1fe4b2c4a198f8ad61a3 1505 | languageName: node 1506 | linkType: hard 1507 | 1508 | "unbox-primitive@npm:^1.0.1": 1509 | version: 1.0.1 1510 | resolution: "unbox-primitive@npm:1.0.1" 1511 | dependencies: 1512 | function-bind: ^1.1.1 1513 | has-bigints: ^1.0.1 1514 | has-symbols: ^1.0.2 1515 | which-boxed-primitive: ^1.0.2 1516 | checksum: 89d950e18fb45672bc6b3c961f1e72c07beb9640c7ceed847b571ba6f7d2af570ae1a2584cfee268b9d9ea1e3293f7e33e0bc29eaeb9f8e8a0bab057ff9e6bba 1517 | languageName: node 1518 | linkType: hard 1519 | 1520 | "util-deprecate@npm:^1.0.1": 1521 | version: 1.0.2 1522 | resolution: "util-deprecate@npm:1.0.2" 1523 | checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 1524 | languageName: node 1525 | linkType: hard 1526 | 1527 | "util@npm:0.10.3": 1528 | version: 0.10.3 1529 | resolution: "util@npm:0.10.3" 1530 | dependencies: 1531 | inherits: 2.0.1 1532 | checksum: bd800f5d237a82caddb61723a6cbe45297d25dd258651a31335a4d5d981fd033cb4771f82db3d5d59b582b187cb69cfe727dc6f4d8d7826f686ee6c07ce611e0 1533 | languageName: node 1534 | linkType: hard 1535 | 1536 | "validate-npm-package-license@npm:^3.0.1": 1537 | version: 3.0.4 1538 | resolution: "validate-npm-package-license@npm:3.0.4" 1539 | dependencies: 1540 | spdx-correct: ^3.0.0 1541 | spdx-expression-parse: ^3.0.0 1542 | checksum: 35703ac889d419cf2aceef63daeadbe4e77227c39ab6287eeb6c1b36a746b364f50ba22e88591f5d017bc54685d8137bc2d328d0a896e4d3fd22093c0f32a9ad 1543 | languageName: node 1544 | linkType: hard 1545 | 1546 | "webidl-conversions@npm:^3.0.0": 1547 | version: 3.0.1 1548 | resolution: "webidl-conversions@npm:3.0.1" 1549 | checksum: c92a0a6ab95314bde9c32e1d0a6dfac83b578f8fa5f21e675bc2706ed6981bc26b7eb7e6a1fab158e5ce4adf9caa4a0aee49a52505d4d13c7be545f15021b17c 1550 | languageName: node 1551 | linkType: hard 1552 | 1553 | "whatwg-url@npm:^5.0.0": 1554 | version: 5.0.0 1555 | resolution: "whatwg-url@npm:5.0.0" 1556 | dependencies: 1557 | tr46: ~0.0.3 1558 | webidl-conversions: ^3.0.0 1559 | checksum: b8daed4ad3356cc4899048a15b2c143a9aed0dfae1f611ebd55073310c7b910f522ad75d727346ad64203d7e6c79ef25eafd465f4d12775ca44b90fa82ed9e2c 1560 | languageName: node 1561 | linkType: hard 1562 | 1563 | "which-boxed-primitive@npm:^1.0.2": 1564 | version: 1.0.2 1565 | resolution: "which-boxed-primitive@npm:1.0.2" 1566 | dependencies: 1567 | is-bigint: ^1.0.1 1568 | is-boolean-object: ^1.1.0 1569 | is-number-object: ^1.0.4 1570 | is-string: ^1.0.5 1571 | is-symbol: ^1.0.3 1572 | checksum: 53ce774c7379071729533922adcca47220228405e1895f26673bbd71bdf7fb09bee38c1d6399395927c6289476b5ae0629863427fd151491b71c4b6cb04f3a5e 1573 | languageName: node 1574 | linkType: hard 1575 | 1576 | "which@npm:^1.2.9": 1577 | version: 1.3.1 1578 | resolution: "which@npm:1.3.1" 1579 | dependencies: 1580 | isexe: ^2.0.0 1581 | bin: 1582 | which: ./bin/which 1583 | checksum: f2e185c6242244b8426c9df1510e86629192d93c1a986a7d2a591f2c24869e7ffd03d6dac07ca863b2e4c06f59a4cc9916c585b72ee9fa1aa609d0124df15e04 1584 | languageName: node 1585 | linkType: hard 1586 | 1587 | "wide-align@npm:^1.1.2": 1588 | version: 1.1.5 1589 | resolution: "wide-align@npm:1.1.5" 1590 | dependencies: 1591 | string-width: ^1.0.2 || 2 || 3 || 4 1592 | checksum: d5fc37cd561f9daee3c80e03b92ed3e84d80dde3365a8767263d03dacfc8fa06b065ffe1df00d8c2a09f731482fcacae745abfbb478d4af36d0a891fad4834d3 1593 | languageName: node 1594 | linkType: hard 1595 | 1596 | "wordwrap@npm:^1.0.0": 1597 | version: 1.0.0 1598 | resolution: "wordwrap@npm:1.0.0" 1599 | checksum: 2a44b2788165d0a3de71fd517d4880a8e20ea3a82c080ce46e294f0b68b69a2e49cff5f99c600e275c698a90d12c5ea32aff06c311f0db2eb3f1201f3e7b2a04 1600 | languageName: node 1601 | linkType: hard 1602 | 1603 | "wrap-ansi@npm:^7.0.0": 1604 | version: 7.0.0 1605 | resolution: "wrap-ansi@npm:7.0.0" 1606 | dependencies: 1607 | ansi-styles: ^4.0.0 1608 | string-width: ^4.1.0 1609 | strip-ansi: ^6.0.0 1610 | checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b 1611 | languageName: node 1612 | linkType: hard 1613 | 1614 | "wrappy@npm:1": 1615 | version: 1.0.2 1616 | resolution: "wrappy@npm:1.0.2" 1617 | checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 1618 | languageName: node 1619 | linkType: hard 1620 | 1621 | "y18n@npm:^5.0.5": 1622 | version: 5.0.8 1623 | resolution: "y18n@npm:5.0.8" 1624 | checksum: 54f0fb95621ee60898a38c572c515659e51cc9d9f787fb109cef6fde4befbe1c4602dc999d30110feee37456ad0f1660fa2edcfde6a9a740f86a290999550d30 1625 | languageName: node 1626 | linkType: hard 1627 | 1628 | "yallist@npm:^4.0.0": 1629 | version: 4.0.0 1630 | resolution: "yallist@npm:4.0.0" 1631 | checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5 1632 | languageName: node 1633 | linkType: hard 1634 | 1635 | "yargs-parser@npm:^20.2.2": 1636 | version: 20.2.9 1637 | resolution: "yargs-parser@npm:20.2.9" 1638 | checksum: 8bb69015f2b0ff9e17b2c8e6bfe224ab463dd00ca211eece72a4cd8a906224d2703fb8a326d36fdd0e68701e201b2a60ed7cf81ce0fd9b3799f9fe7745977ae3 1639 | languageName: node 1640 | linkType: hard 1641 | 1642 | "yargs@npm:^16.2.0": 1643 | version: 16.2.0 1644 | resolution: "yargs@npm:16.2.0" 1645 | dependencies: 1646 | cliui: ^7.0.2 1647 | escalade: ^3.1.1 1648 | get-caller-file: ^2.0.5 1649 | require-directory: ^2.1.1 1650 | string-width: ^4.2.0 1651 | y18n: ^5.0.5 1652 | yargs-parser: ^20.2.2 1653 | checksum: b14afbb51e3251a204d81937c86a7e9d4bdbf9a2bcee38226c900d00f522969ab675703bee2a6f99f8e20103f608382936034e64d921b74df82b63c07c5e8f59 1654 | languageName: node 1655 | linkType: hard 1656 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | Using SSH: 30 | 31 | ``` 32 | $ USE_SSH=true yarn deploy 33 | ``` 34 | 35 | Not using SSH: 36 | 37 | ``` 38 | $ GIT_USER= yarn deploy 39 | ``` 40 | 41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 42 | -------------------------------------------------------------------------------- /website/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /website/docs/api-versions/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "API Versions", 3 | "position": 3 4 | } 5 | -------------------------------------------------------------------------------- /website/docs/api-versions/gRPC.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: gRPC 3 | title: gRPC 4 | sidebar_position: 0 5 | --- 6 | 7 | v3 of the Export API introduces a gRPC API. One of the major upsides of using the gRPC protocol is a stream of progress updates and finally streaming the file back to the client. 8 | 9 | :::tip Client Package 10 | The `@fyko/export-api` package includes a typed JavaScript client and will be referenced in [Examples](#examples). 11 | ::: 12 | 13 | 14 | 15 | ## Protobuf Definition 16 | 17 | :::tip Server Reflection 18 | The gRPC service has [server reflection](https://github.com/grpc/grpc/blob/master/doc/server-reflection.md), allowing you to test the API in Postman. 19 | ::: 20 | 21 | ```protobuf 22 | service Exporter { 23 | rpc CreateExport (CreateExportRequest) returns (stream CreateExportResponse); 24 | } 25 | 26 | enum ExportFormat { 27 | PlainText = 0; 28 | HtmlDark = 1; 29 | HtmlLight = 2; 30 | CSV = 3; 31 | JSON = 4; 32 | } 33 | 34 | message CreateExportRequest { 35 | string token = 1; 36 | string channel_id = 2; 37 | ExportFormat export_format = 3; 38 | string date_format = 4; 39 | string after = 5; 40 | string before = 6; 41 | } 42 | 43 | message CreateExportResponse { 44 | oneof ResponseType { 45 | double progress = 1; 46 | ExportComplete data = 2; 47 | } 48 | } 49 | 50 | message ExportComplete { 51 | int32 message_count = 1; 52 | bytes data = 2; 53 | } 54 | ``` 55 | 56 | ## `Exporter/CreateExport` 57 | 58 | > `rpc CreateExport (CreateExportRequest) returns (stream CreateExportResponse);` 59 | 60 | ### Export Formats Enum 61 | 62 | | **Type** | **ID** | **Description** | **File Extension** | 63 | | --------- | ------ | --------------------------------------- | ------------------ | 64 | | PlainText | 0 | Export to a plaintext file | txt | 65 | | HtmlDark | 1 | Export to an HTML file in dark mode | html | 66 | | HtmlLight | 2 | Export to an HTML file in light mode | html | 67 | | CSV | 3 | Export to a comma separated values file | csv | 68 | | JSON | 4 | Export to a JSON file | json | 69 | 70 | ### CreateExportRequest 71 | 72 | | **Field** | **Type** | **Description** | 73 | | ------------- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 74 | | token | string | The bot token for performing requests | 75 | | channel_id | string | The id of the channel to export | 76 | | export_format | ?[ExportFormat](#export-formats-enum) | The format to export the channel as, defaults to `PlainText` | 77 | | date_format | ?string | The [date format](https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings) for dates in exported files, defaults to `dd-MMM-yy hh:mm tt` | 78 | | after | ?string | Only include messages sent after this date | 79 | | before | ?string | Only include messages sent before this date | 80 | 81 | ### CreateExportResponse 82 | 83 | | **Field** | **Type** | **Description** | 84 | | --------- | ---------------------------------- | ------------------------------------------------- | 85 | | progress | int64 | A decimal representing the progress of the export | 86 | | data | ?[ExportComplete](#exportcomplete) | The file data once `progress` equals `1` | 87 | 88 | ### ExportComplete 89 | 90 | | **Field** | **Type** | **Description** | 91 | | ------------- | -------- | -------------------------------- | 92 | | message_count | int | The number of messages exported | 93 | | data | byte[] | The exported file in 32kb chunks | 94 | 95 | ## Examples 96 | 97 | ### High-level 98 | This example uses the new `createExport`, `createExportedClient`, and `promisifyExportResult` functions released in `@fyko/export-api@0.3`. 99 | 100 | ```ts 101 | import { writeFile } from "fs/promises"; 102 | import { createExport, createExporterClient, promisifyExportResult } from "@fyko/export-api/client"; 103 | import { 104 | ExportFormat 105 | } from "@fyko/export-api/types"; 106 | 107 | const stream = createExport(client, { 108 | channelId: process.env.DISCORD_CHANNEL!, 109 | token: process.env.DISCORD_TOKEN!, 110 | exportFormat: ExportFormat.HTMLDARK, 111 | }); 112 | 113 | stream.on("progress", (progress) => console.log(`progress: ${progress}`)); 114 | 115 | const [count, file] = await promisifyExportResult(stream); 116 | 117 | console.log(`export created with ${count} messages (${file.byteLength} bytes)`); 118 | await writeFile("./foo.html", file); 119 | ``` 120 | 121 | ### Low-level 122 | ```ts 123 | import { credentials } from "@grpc/grpc-js"; 124 | import { ExporterClient } from "@fyko/export-api/client"; 125 | import { 126 | CreateExportRequest, 127 | CreateExportResponse, 128 | ExportFormat, 129 | } from "@fyko/export-api/types"; 130 | import { writeFile } from "fs/promises"; 131 | 132 | // creates a new gRPC client 133 | const client = new ExporterClient( 134 | `localhost:${process.env.PORT}`, 135 | credentials.createInsecure() 136 | ); 137 | 138 | void (async () => { 139 | // new CreateExport Request 140 | const request = new CreateExportRequest(); 141 | // set required options 142 | request.setChannelId(process.env.DISCORD_CHANNEL!); 143 | request.setToken(process.env.DISCORD_TOKEN!); 144 | // set optional options 145 | request.setExportFormat(ExportFormat.HTMLDARK); 146 | 147 | // 148 | return new Promise(async (res, rej) => { 149 | // "POST" the request 150 | const stream = client.createExport(request); 151 | 152 | const chunks: (string | Uint8Array)[] = []; 153 | let progress = 0; 154 | stream.on("data", (response: CreateExportResponse) => { 155 | // if `response.progress` is present 156 | const p = response.getProgress(); 157 | if (p && p > progress) { 158 | progress = p; 159 | console.log((p * 100).toFixed() + "%"); 160 | } 161 | 162 | // if finally sending the file itself, push to chunk array 163 | const data = response.getData(); 164 | const inner = data?.getData(); 165 | if (inner) { 166 | console.log(`Inner exists!`); 167 | chunks.push(inner); 168 | } 169 | }); 170 | 171 | // once the server closes the stream, 172 | // we can finally write the file 173 | stream.on("end", async () => { 174 | await writeFile("./foo.html", chunks); 175 | return res(void 0); 176 | }); 177 | 178 | stream.on("error", rej); 179 | }); 180 | })(); 181 | ``` 182 | -------------------------------------------------------------------------------- /website/docs/api-versions/v1.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: v1 3 | title: v1 (discontinued) 4 | sidebar_position: 2 5 | --- 6 | 7 | :::danger API Discontinued 8 | This API version is discontinued, it's advised you use [gRPC](gRPC.md). 9 | ::: 10 | 11 | ## `POST` `/v1/export` 12 | __JSON Body__ 13 | 14 | | **Field** | **Type** | **Description** | 15 | |-----------|----------|---------------------------------------| 16 | | token | string | The bot token for performing requests | 17 | | channelId | string | The id of the channel to export | 18 | 19 | __Response Codes__ 20 | 21 | | **Status** | **Description** | 22 | |------------|----------------------------------------------| 23 | | 200 | Success - exported channel sent as text/html | 24 | | 401 | Unauthorized - bad Discord bot token | 25 | | 409 | Conflict - unknown channel | 26 | 27 | ### Examples 28 | #### Typescript: 29 | ```ts 30 | import fetch from 'node-fetch'; 31 | 32 | async function exportChannel(channelId: string, token: string): Promise { 33 | const response = await fetch('http://exportapi:80/v1/export', { 34 | method: 'POST', 35 | body: JSON.stringify({ channelId, token }), 36 | headers: { 37 | 'Content-Type': 'application/json' 38 | } 39 | }); 40 | if (response.ok) { 41 | return response.buffer(); 42 | } 43 | throw Error('Channel export failed!'); 44 | } 45 | ``` 46 | #### Rust 47 | ```rust 48 | // reqwest = { version = "0.10", features = ["json"] } 49 | use reqwest::Client; 50 | use std::collections::HashMap; 51 | use std::io::copy; 52 | use std::fs::File; 53 | 54 | async fn export_channel(channelId: &str, token: &str) -> Result { 55 | let client = Client::new(); 56 | let mut map = HashMap::new(); 57 | map.insert("channelId", "channel id"); 58 | map.insert("token", "discord token"); 59 | 60 | let file = client.post("http://exportapi:80/v1/export").json(&map).await?.text().await?; 61 | 62 | let dest = File::create("myexport.html")?; 63 | copy(&mut file.as_bytes(), &mut dest)?; 64 | 65 | Ok(dest) 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /website/docs/api-versions/v2.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: v2 3 | title: v2 (discontinued) 4 | sidebar_position: 1 5 | --- 6 | 7 | :::danger API Discontinued 8 | This API version is discontinued, it's advised you use [gRPC](gRPC.md). 9 | ::: 10 | 11 | ## Export Formats Enum 12 | 13 | | **Type** | **ID** | **Description** | **File Extension** | 14 | |-----------|--------|-----------------------------------------|--------------------| 15 | | PlainText | 0 | Export to a plaintext file | txt | 16 | | HtmlDark | 1 | Export to an HTML file in dark mode | html | 17 | | HtmlLight | 2 | Export to an HTML file in light mode | html | 18 | | CSV | 3 | Export to a comma separated values file | csv | 19 | | JSON | 4 | Export to a JSON file | json | 20 | 21 | ## `POST` `/v2/export` 22 | Exports a channel. On success, it returns a file stream. 23 | 24 | __JSON Body__ 25 | 26 | | **Field** | **Type** | **Description** | 27 | |---------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 28 | | token | string | The bot token for performing requests | 29 | | channel_id | string | The id of the channel to export | 30 | | export_format | ?ExportFormat | The format to export the channel as, defaults to `HtmlDark` | 31 | | date_format | ?string | The [date format](https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings) for dates in exported files, defaults to `dd-MMM-yy hh:mm tt` | 32 | | after | ?string | Only include messages sent after this date | 33 | | before | ?string | Only include messages sent before this date | 34 | 35 | ### Examples 36 | #### Typescript: 37 | ```ts 38 | import fetch from 'node-fetch'; 39 | 40 | async function exportChannel(channel_id: string, token: string): Promise { 41 | const response = await fetch('http://exportapi:80/v2/export', { 42 | method: 'POST', 43 | body: JSON.stringify({ channel_id, token }), 44 | headers: { 45 | 'Content-Type': 'application/json' 46 | } 47 | }); 48 | if (response.ok) { 49 | return response.buffer(); 50 | } 51 | throw Error('Channel export failed!'); 52 | } 53 | ``` 54 | #### Rust 55 | ```rust 56 | // reqwest = { version = "0.10", features = ["json"] } 57 | use reqwest::Client; 58 | use std::collections::HashMap; 59 | use std::io::copy; 60 | use std::fs::File; 61 | 62 | async fn export_channel(channelId: &str, token: &str) -> Result { 63 | let client = Client::new(); 64 | let mut map = HashMap::new(); 65 | map.insert("channel_id", "channel id"); 66 | map.insert("token", "discord token"); 67 | 68 | let file = client.post("http://exportapi:80/v2/export").json(&map).await?.text().await?; 69 | 70 | let dest = File::create("myexport.html")?; 71 | copy(&mut file.as_bytes(), &mut dest)?; 72 | 73 | Ok(dest) 74 | } 75 | ``` 76 | -------------------------------------------------------------------------------- /website/docs/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: intro 3 | title: Introduction 4 | sidebar_position: 1 5 | --- 6 | > A gRPC service to create HTML exports of Discord text-channels. 7 | 8 | [![Docs](https://img.shields.io/badge/%F0%9F%93%96-Documentation-informational)](https://fyko.github.io/export-api/docs/intro) 9 | [![License](https://img.shields.io/github/license/fyko/export-api)](https://github.com/fyko/export-api/blob/master/LICENSE.md) 10 | [![Test](https://github.com/Fyko/export-api/workflows/Test/badge.svg)](https://github.com/Fyko/export-api/actions?query=workflow%3ATest) 11 | [![Docker Pulls](https://img.shields.io/badge/-Docker%20Image-grey?logo=docker)](https://github.com/Fyko/export-api/pkgs/container/export-api) 12 | [![Ko-fi Donate](https://img.shields.io/badge/kofi-donate-brightgreen.svg?label=Donate%20with%20Ko-fi&logo=ko-fi&colorB=F16061&link=https://ko-fi.com/carterh&logoColor=FFFFFF)](https://ko-fi.com/carterh) 13 | 14 | ## Usage 15 | ### Docker Image 16 | The Export API can be found on the [GitHub Container Registry](https://pkg.github.com) at [`fyko/export-api`](https://github.com/Fyko/export-api/pkgs/container/export-api). 17 | 18 | ```sh 19 | docker run -p yourport:80 --rm -it ghcr.io/fyko/export-api 20 | ``` 21 | or with Compose 22 | ```yaml 23 | services: 24 | exportapi: 25 | image: ghcr.io/fyko/export-api 26 | ports: 27 | - "yourport:80" 28 | expose: 29 | - "yourport" 30 | ``` 31 | 32 | ### Calling the gRPC API 33 | - [API Versions: gRPC](./api-versions/gRPC) 34 | 35 | ## Thanks 36 | This services utilizes [`Tyrrrz/DiscordChatExporter`](https://github.com/Tyrrrz/DiscordChatExporter) for exporting channels. 37 | -------------------------------------------------------------------------------- /website/docs/setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: setup 3 | title: Setup 4 | sidebar_position: 1 5 | --- 6 | # Setup 7 | 8 | # Docker Compose 9 | :::tip 10 | This is the reccomended way of running Export API. 11 | ::: 12 | 13 | To start using `fyko/export-api`, add the service to your `docker-compose.yml` file! 14 | ```yml 15 | services: 16 | exportapi: 17 | image: ghcr.io/fyko/export-api 18 | expose: 19 | - "80" 20 | ``` 21 | 22 | You can then interact with the API with `http://exportapi/...`. 23 | 24 | # `docker run` 25 | `docker run -p yourport:80 --rm -it ghcr.io/fyko/export-api` 26 | 27 | You can then interact with the API with `http://127.0.0.1:yourport/...`. -------------------------------------------------------------------------------- /website/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Note: type annotations allow type checking and IDEs autocompletion 3 | 4 | const lightCodeTheme = require('prism-react-renderer/themes/github'); 5 | const darkCodeTheme = require('prism-react-renderer/themes/dracula'); 6 | 7 | /** @type {import('@docusaurus/types').Config} */ 8 | const config = { 9 | title: 'Export API', 10 | tagline: 'A gRPC Service to export Discord channels as HTML documents.', 11 | url: 'https://your-docusaurus-test-site.com', 12 | baseUrl: '/export-api/', 13 | onBrokenLinks: 'throw', 14 | onBrokenMarkdownLinks: 'warn', 15 | favicon: 'img/favicon.ico', 16 | organizationName: 'Fyko', // Usually your GitHub org/user name. 17 | projectName: 'export-api', // Usually your repo name. 18 | 19 | presets: [ 20 | [ 21 | 'classic', 22 | /** @type {import('@docusaurus/preset-classic').Options} */ 23 | ({ 24 | docs: { 25 | sidebarPath: require.resolve('./sidebars.js'), 26 | sidebarCollapsible: false, 27 | // Please change this to your repo. 28 | editUrl: 'https://github.com/Fyko/export-api/edit/main/website/', 29 | }, 30 | theme: { 31 | customCss: require.resolve('./src/css/custom.css'), 32 | }, 33 | }), 34 | ], 35 | ], 36 | 37 | themeConfig: 38 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ 39 | ({ 40 | navbar: { 41 | title: 'Export API', 42 | logo: { 43 | alt: 'Export API Logo', 44 | src: 'img/logo.svg', 45 | }, 46 | items: [ 47 | { 48 | type: 'doc', 49 | docId: 'intro', 50 | position: 'left', 51 | label: 'Documentation', 52 | }, 53 | { 54 | href: 'https://github.com/Fyko/export-api', 55 | label: 'GitHub', 56 | position: 'right', 57 | }, 58 | ], 59 | }, 60 | footer: { 61 | style: 'dark', 62 | links: [ 63 | { 64 | title: 'Community', 65 | items: [ 66 | { 67 | label: 'Discord', 68 | href: 'https://discordapp.com/invite/dUrkbpw', 69 | }, 70 | { 71 | label: 'Stack Overflow', 72 | href: 'https://stackoverflow.com/questions/tagged/exportapi', 73 | }, 74 | ], 75 | }, 76 | { 77 | title: 'More', 78 | items: [ 79 | { 80 | label: 'GitHub', 81 | href: 'https://github.com/Fyko/export-api', 82 | }, 83 | { 84 | label: 'Archive Utility', 85 | href: 'https://github.com/Fyko/archive-utility', 86 | } 87 | ], 88 | }, 89 | ], 90 | copyright: `Copyright © ${new Date().getFullYear()} Carter 'Fyko' Himmel. Built with Docusaurus.`, 91 | }, 92 | prism: { 93 | theme: lightCodeTheme, 94 | darkTheme: darkCodeTheme, 95 | additionalLanguages: ['protobuf'], 96 | }, 97 | }), 98 | }; 99 | 100 | module.exports = config; 101 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "2.2.0", 18 | "@docusaurus/preset-classic": "2.2.0", 19 | "@mdx-js/react": "^1.6.22", 20 | "clsx": "^1.1.1", 21 | "prism-react-renderer": "^1.2.1", 22 | "react": "^17.0.1", 23 | "react-dom": "^17.0.1" 24 | }, 25 | "browserslist": { 26 | "production": [">0.5%", "not dead", "not op_mini all"], 27 | "development": [ 28 | "last 1 chrome version", 29 | "last 1 firefox version", 30 | "last 1 safari version" 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /website/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | // @ts-check 13 | 14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 15 | const sidebars = { 16 | // By default, Docusaurus generates a sidebar from the docs folder structure 17 | tutorialSidebar: [{type: 'autogenerated', dirName: '.'}, { type: 'link', label: 'Archive Utility', href: 'https://github.com/Fyko/archive-utility' }], 18 | 19 | // But you can create a sidebar manually 20 | /* 21 | tutorialSidebar: [ 22 | { 23 | type: 'category', 24 | label: 'Tutorial', 25 | items: ['hello'], 26 | }, 27 | ], 28 | */ 29 | }; 30 | 31 | module.exports = sidebars; 32 | -------------------------------------------------------------------------------- /website/src/components/HomepageFeatures/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import styles from './styles.module.css'; 4 | import Link from '@docusaurus/Link'; 5 | 6 | const FeatureList = [ 7 | { 8 | title: 'Start Quickly', 9 | Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, 10 | description: ( 11 | <> 12 | Add a few lines to your Docker Compose file and you're ready to go. 13 | 14 | ), 15 | }, 16 | { 17 | title: 'gRPC Support', 18 | Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, 19 | description: ( 20 | <> 21 | We reccomend using gRPC. It's easy to get started and 22 | supports all of the features of the HTTP API. For more information, 23 | read the gRPC documentation. 24 | 25 | ), 26 | }, 27 | { 28 | title: 'Powered by C#', 29 | Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, 30 | description: ( 31 | <> 32 | Primarily dependent on Tyrrrz/DiscordChatExporter, 33 | we vendor the C# codebase to ensure a performant and reliable experience. 34 | 35 | ), 36 | }, 37 | ]; 38 | 39 | function Feature({Svg, title, description}) { 40 | return ( 41 |
42 |
43 | 44 |
45 |
46 |

{title}

47 |

{description}

48 |
49 |
50 | ); 51 | } 52 | 53 | export default function HomepageFeatures() { 54 | return ( 55 |
56 |
57 |
58 | {FeatureList.map((props, idx) => ( 59 | 60 | ))} 61 |
62 |
63 |
64 | ); 65 | } 66 | -------------------------------------------------------------------------------- /website/src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /website/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #77c2ae; 10 | --ifm-color-primary-dark:#6baf9d; 11 | --ifm-color-primary-darker: #5f9b8b; 12 | --ifm-color-primary-darkest: #53887a; 13 | --ifm-color-primary-light: #85c8b6; 14 | --ifm-color-primary-lighter: #92cebe; 15 | --ifm-color-primary-lightest: #a0d4c6; 16 | --ifm-code-font-size: 95%; 17 | } 18 | 19 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 20 | [data-theme='dark'] { 21 | --ifm-color-primary: #77c2ae; 22 | --ifm-color-primary-dark:#6baf9d; 23 | --ifm-color-primary-darker: #5f9b8b; 24 | --ifm-color-primary-darkest: #53887a; 25 | --ifm-color-primary-light: #85c8b6; 26 | --ifm-color-primary-lighter: #92cebe; 27 | --ifm-color-primary-lightest: #a0d4c6; 28 | } 29 | 30 | .docusaurus-highlight-code-line { 31 | background-color: rgba(0, 0, 0, 0.1); 32 | display: block; 33 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 34 | padding: 0 var(--ifm-pre-padding); 35 | } 36 | 37 | [data-theme='dark'] .docusaurus-highlight-code-line { 38 | background-color: rgba(0, 0, 0, 0.3); 39 | } 40 | -------------------------------------------------------------------------------- /website/src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import Layout from '@theme/Layout'; 4 | import Link from '@docusaurus/Link'; 5 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 6 | import styles from './index.module.css'; 7 | import HomepageFeatures from '@site/src/components/HomepageFeatures'; 8 | 9 | function HomepageHeader() { 10 | const {siteConfig} = useDocusaurusContext(); 11 | return ( 12 |
13 |
14 |

{siteConfig.title}

15 |

{siteConfig.tagline}

16 |
17 | 20 | Get Started 21 | 22 |
23 |
24 |
25 | ); 26 | } 27 | 28 | export default function Home() { 29 | const {siteConfig} = useDocusaurusContext(); 30 | return ( 31 | 34 | 35 |
36 | 37 |
38 |
39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /website/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | } 12 | 13 | @media screen and (max-width: 966px) { 14 | .heroBanner { 15 | padding: 2rem; 16 | } 17 | } 18 | 19 | .buttons { 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | -------------------------------------------------------------------------------- /website/src/pages/markdown-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown page example 3 | --- 4 | 5 | # Markdown page example 6 | 7 | You don't need React to write simple standalone pages. 8 | -------------------------------------------------------------------------------- /website/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fyko/export-api/c309ebe7745437c3082d0b2c2593b2d20f0d4b51/website/static/.nojekyll -------------------------------------------------------------------------------- /website/static/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fyko/export-api/c309ebe7745437c3082d0b2c2593b2d20f0d4b51/website/static/img/docusaurus.png -------------------------------------------------------------------------------- /website/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fyko/export-api/c309ebe7745437c3082d0b2c2593b2d20f0d4b51/website/static/img/favicon.ico -------------------------------------------------------------------------------- /website/static/img/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /website/static/img/quickstart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fyko/export-api/c309ebe7745437c3082d0b2c2593b2d20f0d4b51/website/static/img/quickstart.jpg -------------------------------------------------------------------------------- /website/static/img/undraw_docusaurus_mountain.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /website/static/img/undraw_docusaurus_react.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /website/static/img/undraw_docusaurus_tree.svg: -------------------------------------------------------------------------------- 1 | docu_tree --------------------------------------------------------------------------------