mirror of
https://github.com/discordeno/discordeno.git
synced 2026-05-21 02:40:08 +00:00
feat!: rewrite proxy app with fastify (#3269)
* feat: initial fastify source * chore: remove extra stuff from git ignore * feat: rename to rest passthrough * feat: add swcrc file * feat: add Dockerfile * feat: more rest passthrough stuff * fix: add node_modules to Dockerfile * feat: misc passthrough changes * feat: add host to dockerfile * feat: add version tags and update names * feat: remove the old proxy application * feat: update registry package name * feat: re-add schedule * feat: cliff jumper initi * feat: update changelog * style: git cliff formatting * feat: update cliffjumper rc * feat: updating version for future cliff-jump run * revert: package name back * feat: add release script * feat: update dependabot configuration to manage rest passthrough app * chore: update actions/download-artifact version * feat: adding removal of the version in URL. * feat: making readme better
This commit is contained in:
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@@ -15,3 +15,7 @@ updates:
|
|||||||
schedule:
|
schedule:
|
||||||
# Check for updates to GitHub Actions every week
|
# Check for updates to GitHub Actions every week
|
||||||
interval: 'daily'
|
interval: 'daily'
|
||||||
|
- package-ecosystem: 'npm'
|
||||||
|
directory: '/docker-apps/rest-passthrough'
|
||||||
|
schedule:
|
||||||
|
interval: 'daily'
|
||||||
|
|||||||
@@ -1,23 +1,52 @@
|
|||||||
name: Rest proxy
|
name: Docker App - Rest Passthrough
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'main'
|
- 'main'
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/rest-proxy.yml'
|
- '.github/workflows/docker-app-rest-passthrough.yml'
|
||||||
- 'proxies/rest/**'
|
- 'docker-apps/rest-passthrough/**'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/rest-proxy.yml'
|
- '.github/workflows/docker-app-rest-passthrough.yml'
|
||||||
- 'proxies/rest/**'
|
- 'docker-apps/rest-passthrough/**'
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 0 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
run-release:
|
||||||
|
name: Run release script
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Git config
|
||||||
|
run: |
|
||||||
|
git config user.name github-actions
|
||||||
|
git config user.email github-actions@github.com
|
||||||
|
- name: Run release script
|
||||||
|
run: |
|
||||||
|
yarn release
|
||||||
|
git push && git push --tags
|
||||||
|
|
||||||
|
app-version:
|
||||||
|
name: Get app version
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
version: ${{ steps.package-version.outputs.current-version }}
|
||||||
|
steps:
|
||||||
|
- name: get-npm-version
|
||||||
|
id: package-version
|
||||||
|
uses: martinbeentjes/npm-get-version-action@v1.3.1
|
||||||
|
with:
|
||||||
|
path: docker-apps/rest-passthrough
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build docker image
|
name: Build docker image
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
needs: app-version
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Cache Docker layers
|
- name: Cache Docker layers
|
||||||
@@ -35,10 +64,12 @@ jobs:
|
|||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
push: false
|
push: false
|
||||||
tags: discordeno/rest-proxy:latest
|
tags:
|
||||||
context: proxies/rest
|
- 'discordeno/app-rest-passthrough:latest'
|
||||||
|
- 'discordeno/app-rest-passthrough:v${{ needs.app-version.outputs.version }}'
|
||||||
|
context: docker-apps/rest-passthrough
|
||||||
target: runner
|
target: runner
|
||||||
outputs: type=docker,dest=/tmp/rest-proxy-image.tar
|
outputs: type=docker,dest=/tmp/rest-passthrough-image.tar
|
||||||
cache-from: type=local,src=/tmp/.buildx-cache
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
||||||
- # Temp fix
|
- # Temp fix
|
||||||
@@ -51,8 +82,8 @@ jobs:
|
|||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: rest-proxy-image
|
name: rest-passthrough-image
|
||||||
path: /tmp/rest-proxy-image.tar
|
path: /tmp/rest-passthrough-image.tar
|
||||||
|
|
||||||
image-scan:
|
image-scan:
|
||||||
name: Image scan
|
name: Image scan
|
||||||
@@ -63,16 +94,16 @@ jobs:
|
|||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Download artifact
|
- name: Download artifact
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: rest-proxy-image
|
name: rest-passthrough-image
|
||||||
path: /tmp
|
path: /tmp
|
||||||
- name: Load Docker image
|
- name: Load Docker image
|
||||||
run: docker load --input /tmp/rest-proxy-image.tar
|
run: docker load --input /tmp/rest-passthrough-image.tar
|
||||||
- name: Run Trivy vulnerability scanner
|
- name: Run Trivy vulnerability scanner
|
||||||
uses: aquasecurity/trivy-action@master
|
uses: aquasecurity/trivy-action@master
|
||||||
with:
|
with:
|
||||||
image-ref: 'discordeno/rest-proxy:latest'
|
image-ref: 'discordeno/app-rest-passthrough:latest'
|
||||||
format: 'table'
|
format: 'table'
|
||||||
exit-code: '0'
|
exit-code: '0'
|
||||||
ignore-unfixed: true
|
ignore-unfixed: true
|
||||||
@@ -82,7 +113,7 @@ jobs:
|
|||||||
uses: aquasecurity/trivy-action@master
|
uses: aquasecurity/trivy-action@master
|
||||||
if: ${{ github.event_name == 'schedule' || github.event_name == 'push' }}
|
if: ${{ github.event_name == 'schedule' || github.event_name == 'push' }}
|
||||||
with:
|
with:
|
||||||
image-ref: 'discordeno/rest-proxy:latest'
|
image-ref: 'discordeno/app-rest-passthrough:latest'
|
||||||
exit-code: '0'
|
exit-code: '0'
|
||||||
vuln-type: 'os,library'
|
vuln-type: 'os,library'
|
||||||
severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'
|
severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'
|
||||||
@@ -101,8 +132,8 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||||
with:
|
with:
|
||||||
image: 'discordeno/rest-proxy:latest'
|
image: 'discordeno/app-rest-passthrough:latest'
|
||||||
args: --file=proxies/rest/Dockerfile
|
args: --file=docker-apps/rest-passthrough/Dockerfile
|
||||||
- name: Upload result to GitHub Code Scanning
|
- name: Upload result to GitHub Code Scanning
|
||||||
if: ${{ github.event_name == 'schedule' || github.event_name == 'push' }}
|
if: ${{ github.event_name == 'schedule' || github.event_name == 'push' }}
|
||||||
uses: github/codeql-action/upload-sarif@v3
|
uses: github/codeql-action/upload-sarif@v3
|
||||||
@@ -111,7 +142,7 @@ jobs:
|
|||||||
|
|
||||||
build-all-arch:
|
build-all-arch:
|
||||||
name: Build image for all architectures
|
name: Build image for all architectures
|
||||||
needs: build
|
needs: [build, app-version]
|
||||||
if: ${{ github.event_name != 'schedule' }}
|
if: ${{ github.event_name != 'schedule' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -131,9 +162,12 @@ jobs:
|
|||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: proxies/rest
|
context: docker-apps/rest-passthrough
|
||||||
push: false
|
push: false
|
||||||
tags: 'discordeno/rest-proxy:latest'
|
tags:
|
||||||
|
- 'discordeno/app-rest-passthrough:latest'
|
||||||
|
- 'discordeno/app-rest-passthrough:v${{ needs.app-version.outputs.version }}'
|
||||||
|
|
||||||
# linux/s390x stuck at yarn install, remove it for now
|
# linux/s390x stuck at yarn install, remove it for now
|
||||||
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le
|
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le
|
||||||
target: runner
|
target: runner
|
||||||
@@ -149,7 +183,7 @@ jobs:
|
|||||||
|
|
||||||
publish:
|
publish:
|
||||||
name: Publish image
|
name: Publish image
|
||||||
needs: build-all-arch
|
needs: [run-release, build-all-arch, app-version]
|
||||||
if: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
|
if: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
@@ -171,9 +205,11 @@ jobs:
|
|||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: proxies/rest
|
context: docker-apps/rest-passthrough
|
||||||
push: true
|
push: true
|
||||||
tags: 'ghcr.io/discordeno/rest-proxy:latest'
|
tags:
|
||||||
|
- 'ghcr.io/discordeno/app-rest-passthrough:latest'
|
||||||
|
- 'ghcr.io/discordeno/app-rest-passthrough:v${{ needs.app-version.outputs.version }}'
|
||||||
# linux/s390x stuck at yarn install, remove it for now
|
# linux/s390x stuck at yarn install, remove it for now
|
||||||
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le
|
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le
|
||||||
target: runner
|
target: runner
|
||||||
0
docker-apps/README.md
Normal file
0
docker-apps/README.md
Normal file
4
docker-apps/rest-passthrough/.cliff-jumperrc.yml
Normal file
4
docker-apps/rest-passthrough/.cliff-jumperrc.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
name: app-rest-passthrough
|
||||||
|
org: discordeno
|
||||||
|
packagePath: .
|
||||||
|
commitMessageTemplate: 'chore(release): release {{new-version}}'
|
||||||
5
docker-apps/rest-passthrough/.gitattributes
vendored
Normal file
5
docker-apps/rest-passthrough/.gitattributes
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
* text eol=lf
|
||||||
|
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
*.svg binary
|
||||||
35
docker-apps/rest-passthrough/.gitignore
vendored
Normal file
35
docker-apps/rest-passthrough/.gitignore
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# dependencies
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
.pnp.*
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/sdks
|
||||||
|
!.yarn/versions
|
||||||
|
# testing
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# build
|
||||||
|
dist
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
# turbo
|
||||||
|
.turbo
|
||||||
@@ -22,4 +22,4 @@
|
|||||||
"noInterop": false
|
"noInterop": false
|
||||||
},
|
},
|
||||||
"sourceMaps": "inline"
|
"sourceMaps": "inline"
|
||||||
}
|
}
|
||||||
893
docker-apps/rest-passthrough/.yarn/releases/yarn-4.0.2.cjs
vendored
Executable file
893
docker-apps/rest-passthrough/.yarn/releases/yarn-4.0.2.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
7
docker-apps/rest-passthrough/.yarnrc.yml
Normal file
7
docker-apps/rest-passthrough/.yarnrc.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
compressionLevel: mixed
|
||||||
|
|
||||||
|
enableGlobalCache: false
|
||||||
|
|
||||||
|
nodeLinker: node-modules
|
||||||
|
|
||||||
|
yarnPath: .yarn/releases/yarn-4.0.2.cjs
|
||||||
4
docker-apps/rest-passthrough/CHANGELOG.md
Normal file
4
docker-apps/rest-passthrough/CHANGELOG.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
45
docker-apps/rest-passthrough/Dockerfile
Normal file
45
docker-apps/rest-passthrough/Dockerfile
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# we node 18 alpine 3.19 as base image
|
||||||
|
# we use multi stage build in this file
|
||||||
|
|
||||||
|
# deps
|
||||||
|
# contain all dependencies including dev dependencies
|
||||||
|
# builder
|
||||||
|
# contains all compiled files
|
||||||
|
# runner
|
||||||
|
# the final image, with only the dependencies and compiled files
|
||||||
|
|
||||||
|
# build only with the platform of the host machine, since it only uses for dev purposes
|
||||||
|
FROM --platform=$BUILDPLATFORM node:18.19.0-alpine3.19 AS deps
|
||||||
|
WORKDIR /app
|
||||||
|
# copy necessary for install dependencies
|
||||||
|
COPY package.json yarn.lock .yarnrc.yml ./
|
||||||
|
COPY ./.yarn/releases ./.yarn/releases
|
||||||
|
# install dependencies
|
||||||
|
RUN yarn install --immutable
|
||||||
|
|
||||||
|
# build only with the platform of the host machine, since we just need its files
|
||||||
|
FROM --platform=$BUILDPLATFORM node:18.19.0-alpine3.19 AS builder
|
||||||
|
# copy the dependencies (node_modules) from the deps image
|
||||||
|
COPY --from=deps /app /app
|
||||||
|
WORKDIR /app
|
||||||
|
# copy the source files
|
||||||
|
COPY src/ src/
|
||||||
|
# copy the compiler config
|
||||||
|
COPY .swcrc ./
|
||||||
|
# compile the files
|
||||||
|
RUN yarn build
|
||||||
|
|
||||||
|
FROM node:18.19.0-alpine3.19 AS runner
|
||||||
|
# copy the compiled files from the builder image
|
||||||
|
COPY --from=builder /app/dist /app/dist
|
||||||
|
# copy the dependencies from the deps image
|
||||||
|
COPY --from=deps /app/node_modules /app/node_modules
|
||||||
|
COPY --from=deps /app/.yarn /app/.yarn
|
||||||
|
WORKDIR /app
|
||||||
|
# copy necessary files
|
||||||
|
COPY package.json yarn.lock .yarnrc.yml ./
|
||||||
|
ENV HOST=0.0.0.0
|
||||||
|
# open port 8000
|
||||||
|
EXPOSE 8000
|
||||||
|
# set default command
|
||||||
|
CMD ["yarn" ,"start:prod"]
|
||||||
201
docker-apps/rest-passthrough/LICENSE
Normal file
201
docker-apps/rest-passthrough/LICENSE
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright 2021 - 2023 Discordeno
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
28
docker-apps/rest-passthrough/README.md
Normal file
28
docker-apps/rest-passthrough/README.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Discordeno Rest Passthrough
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Before running the app, make sure you have the following prerequisites installed:
|
||||||
|
|
||||||
|
- Docker: [Installation Guide](https://docs.docker.com/get-docker/)
|
||||||
|
- Discordeno: [GitHub Repository](https://github.com/discordeno/discordeno)
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
1. `docker pull ghcr.io/discordeno/app-rest-passthrough:latest`
|
||||||
|
2. Create an environment file (you can use `-e` flags instead), example: `./my-env`
|
||||||
|
3. `docker run --detach --env-file ./my-env -p 8000:8000 --name dd-rest discordeno/app-rest-passthrough`
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The app can be configured using environment variables. The following variables are available:
|
||||||
|
|
||||||
|
- `DISCORD_TOKEN`: The Discord bot token used for authentication.
|
||||||
|
- `HOST`: The host to bind the application to, for Docker it should be `0.0.0.0`. Defaults to `localhost`.
|
||||||
|
- `AUTHORIZATION_TOKEN`: The token that will be used to authorize the requests made. This can be anything generated by you.
|
||||||
|
|
||||||
|
You can set these variables either in a `.env` file or directly in your Docker command.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the [Apache 2.0 License](LICENSE).
|
||||||
83
docker-apps/rest-passthrough/cliff.toml
Normal file
83
docker-apps/rest-passthrough/cliff.toml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# git-cliff ~ default configuration file
|
||||||
|
# https://git-cliff.org/docs/configuration
|
||||||
|
#
|
||||||
|
# Lines starting with "#" are comments.
|
||||||
|
# Configuration options are organized into tables and keys.
|
||||||
|
# See documentation for more information on available options.
|
||||||
|
|
||||||
|
[changelog]
|
||||||
|
# changelog header
|
||||||
|
header = """
|
||||||
|
# Changelog\n
|
||||||
|
All notable changes to this project will be documented in this file.\n
|
||||||
|
"""
|
||||||
|
# template for the changelog body
|
||||||
|
# https://keats.github.io/tera/docs/#introduction
|
||||||
|
body = """
|
||||||
|
{% if version %}\
|
||||||
|
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||||
|
{% else %}\
|
||||||
|
## [unreleased]
|
||||||
|
{% endif %}\
|
||||||
|
{% for group, commits in commits | group_by(attribute="group") %}
|
||||||
|
### {{ group | upper_first }}
|
||||||
|
{% for commit in commits %}
|
||||||
|
- {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}\n
|
||||||
|
"""
|
||||||
|
# remove the leading and trailing whitespace from the template
|
||||||
|
trim = true
|
||||||
|
# changelog footer
|
||||||
|
footer = """
|
||||||
|
<!-- generated by git-cliff -->
|
||||||
|
"""
|
||||||
|
# postprocessors
|
||||||
|
postprocessors = [
|
||||||
|
# { pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL
|
||||||
|
]
|
||||||
|
[git]
|
||||||
|
# parse the commits based on https://www.conventionalcommits.org
|
||||||
|
conventional_commits = true
|
||||||
|
# filter out the commits that are not conventional
|
||||||
|
filter_unconventional = true
|
||||||
|
# process each line of a commit as an individual commit
|
||||||
|
split_commits = false
|
||||||
|
# regex for preprocessing the commit messages
|
||||||
|
commit_preprocessors = [
|
||||||
|
# { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"}, # replace issue numbers
|
||||||
|
]
|
||||||
|
# regex for parsing and grouping commits
|
||||||
|
commit_parsers = [
|
||||||
|
{ message = "^feat", group = "Features" },
|
||||||
|
{ message = "^fix", group = "Bug Fixes" },
|
||||||
|
{ message = "^doc", group = "Documentation" },
|
||||||
|
{ message = "^perf", group = "Performance" },
|
||||||
|
{ message = "^refactor", group = "Refactor" },
|
||||||
|
{ message = "^style", group = "Styling" },
|
||||||
|
{ message = "^test", group = "Testing" },
|
||||||
|
{ message = "^chore\\(release\\): prepare for", skip = true },
|
||||||
|
{ message = "^chore\\(deps\\)", skip = true },
|
||||||
|
{ message = "^chore\\(pr\\)", skip = true },
|
||||||
|
{ message = "^chore\\(pull\\)", skip = true },
|
||||||
|
{ message = "^chore|ci", group = "Miscellaneous Tasks" },
|
||||||
|
{ body = ".*security", group = "Security" },
|
||||||
|
{ message = "^revert", group = "Revert" },
|
||||||
|
]
|
||||||
|
# protect breaking changes from being skipped due to matching a skipping commit_parser
|
||||||
|
protect_breaking_commits = false
|
||||||
|
# filter out the commits that are not matched by commit parsers
|
||||||
|
filter_commits = false
|
||||||
|
# regex for matching git tags
|
||||||
|
tag_pattern = "v[0-9].*"
|
||||||
|
|
||||||
|
# regex for skipping tags
|
||||||
|
skip_tags = "v0.1.0-beta.1"
|
||||||
|
# regex for ignoring tags
|
||||||
|
ignore_tags = ""
|
||||||
|
# sort the tags topologically
|
||||||
|
topo_order = false
|
||||||
|
# sort the commits inside sections by oldest/newest order
|
||||||
|
sort_commits = "oldest"
|
||||||
|
# limit the number of commits included in the changelog.
|
||||||
|
# limit_commits = 42
|
||||||
26
docker-apps/rest-passthrough/package.json
Normal file
26
docker-apps/rest-passthrough/package.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "rest-passthrough",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "swc src --delete-dir-on-start --out-dir dist",
|
||||||
|
"start:dev": "yarn exec node -r dotenv/config dist/server.js",
|
||||||
|
"start:prod": "yarn exec node ./dist/server.js",
|
||||||
|
"release": "cliff-jumper",
|
||||||
|
"setup-dd": ""
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@discordeno/rest": "19.0.0-next.fb947f5",
|
||||||
|
"@fastify/env": "^4.3.0",
|
||||||
|
"@fastify/helmet": "^11.1.1",
|
||||||
|
"fastify": "^4.24.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@favware/cliff-jumper": "^2.2.3",
|
||||||
|
"@swc/cli": "^0.1.63",
|
||||||
|
"@swc/core": "^1.3.100",
|
||||||
|
"dotenv": "^16.3.1"
|
||||||
|
},
|
||||||
|
"packageManager": "yarn@4.0.2"
|
||||||
|
}
|
||||||
50
docker-apps/rest-passthrough/src/fastify.ts
Normal file
50
docker-apps/rest-passthrough/src/fastify.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import fastifyEnv from '@fastify/env'
|
||||||
|
import fastifyHelmet from '@fastify/helmet'
|
||||||
|
import fastify, { type FastifyInstance } from 'fastify'
|
||||||
|
|
||||||
|
export const buildFastifyApp = async (): Promise<FastifyInstance> => {
|
||||||
|
const app = await fastify()
|
||||||
|
|
||||||
|
await app.register(fastifyEnv, {
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
HOST: {
|
||||||
|
type: 'string',
|
||||||
|
default: 'localhost',
|
||||||
|
},
|
||||||
|
DISCORD_TOKEN: {
|
||||||
|
type: 'string',
|
||||||
|
minLength: 1,
|
||||||
|
},
|
||||||
|
AUTHORIZATION_TOKEN: {
|
||||||
|
type: 'string',
|
||||||
|
minLength: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ['DISCORD_TOKEN', 'AUTHORIZATION_TOKEN'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await app.register(fastifyHelmet)
|
||||||
|
|
||||||
|
app.addHook('onRequest', async (request, reply) => {
|
||||||
|
if (request.headers.authorization !== request.server.config.AUTHORIZATION_TOKEN) {
|
||||||
|
reply.status(401).send({
|
||||||
|
message: 'Credentials not valid.',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'fastify' {
|
||||||
|
interface FastifyInstance {
|
||||||
|
config: {
|
||||||
|
HOST: string
|
||||||
|
DISCORD_TOKEN: string
|
||||||
|
AUTHORIZATION_TOKEN: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
56
docker-apps/rest-passthrough/src/server.ts
Normal file
56
docker-apps/rest-passthrough/src/server.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { createRestManager, type RequestMethods } from '@discordeno/rest'
|
||||||
|
import { buildFastifyApp } from './fastify.js'
|
||||||
|
|
||||||
|
const app = await buildFastifyApp()
|
||||||
|
|
||||||
|
if (!app.config.DISCORD_TOKEN || !app.config.AUTHORIZATION_TOKEN) {
|
||||||
|
console.error('Missing environment variables. Both DISCORD_TOKEN and AUTHORIZATION_TOKEN are required.')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const discordRestManager = createRestManager({
|
||||||
|
token: app.config.DISCORD_TOKEN,
|
||||||
|
})
|
||||||
|
|
||||||
|
app.get('/timecheck', async (request, reply) => {
|
||||||
|
reply.status(200).send({
|
||||||
|
message: Date.now(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
app.all('/*', async (request, reply) => {
|
||||||
|
let url = request.originalUrl
|
||||||
|
|
||||||
|
if (url.startsWith('/v')) {
|
||||||
|
url = url.slice(url.indexOf('/', 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await discordRestManager.makeRequest(request.method as RequestMethods, url, {
|
||||||
|
body: request.body,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
reply.status(200).send(result)
|
||||||
|
} else {
|
||||||
|
reply.status(204).send({})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
app.log.error(error)
|
||||||
|
|
||||||
|
reply.status(500).send({
|
||||||
|
message: error,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
await app.listen({
|
||||||
|
host: app.config.HOST,
|
||||||
|
port: 8000,
|
||||||
|
})
|
||||||
|
console.log(`Proxy listening on port 8000`)
|
||||||
|
} catch (error) {
|
||||||
|
app.log.error(error)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
2079
docker-apps/rest-passthrough/yarn.lock
Normal file
2079
docker-apps/rest-passthrough/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
873
proxies/rest/.yarn/releases/yarn-3.5.0.cjs
vendored
873
proxies/rest/.yarn/releases/yarn-3.5.0.cjs
vendored
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
nodeLinker: node-modules
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
# we node 18 alpine 3.18 as base image
|
|
||||||
# we use multi stage build in this file
|
|
||||||
# deps: contain all dependencies including dev dependencies
|
|
||||||
# builder: contains all compiled files
|
|
||||||
# prod-deps: contains only dependencies excluding dev dependencies
|
|
||||||
# runner: the final image, with only the dependencies and compiled files
|
|
||||||
|
|
||||||
# build only with the platform of the host machine, since it only uses for dev purposes
|
|
||||||
FROM --platform=$BUILDPLATFORM node:18.16.0-alpine3.18 AS deps
|
|
||||||
WORKDIR /app
|
|
||||||
# copy necessary for install dependencies
|
|
||||||
COPY package.json yarn.lock ./
|
|
||||||
# install dependencies
|
|
||||||
RUN yarn install
|
|
||||||
|
|
||||||
# build only with the platform of the host machine, since we just need its files
|
|
||||||
FROM --platform=$BUILDPLATFORM node:18.16.0-alpine3.18 AS builder
|
|
||||||
# copy the dependencies (node_modules) from the deps image
|
|
||||||
COPY --from=deps /app /app
|
|
||||||
WORKDIR /app
|
|
||||||
# copy the source files
|
|
||||||
COPY src/ src/
|
|
||||||
# copy the compiler config
|
|
||||||
COPY .swcrc ./
|
|
||||||
# compile the files
|
|
||||||
RUN yarn build
|
|
||||||
|
|
||||||
FROM node:18.16.0-alpine3.18 AS prod-deps
|
|
||||||
WORKDIR /app
|
|
||||||
# copy necessary files for install dependencies
|
|
||||||
COPY package.json yarn.lock .yarnrc.yml ./
|
|
||||||
COPY ./.yarn/plugins ./.yarn/plugins
|
|
||||||
COPY ./.yarn/releases ./.yarn/releases
|
|
||||||
# config yarn to install only prod dependencies
|
|
||||||
RUN yarn set version berry
|
|
||||||
# install prod dependencies
|
|
||||||
RUN yarn workspaces focus --all --production
|
|
||||||
|
|
||||||
FROM node:18.16.0-alpine3.18 AS runner
|
|
||||||
# copy the compiled files from the builder image
|
|
||||||
COPY --from=builder /app/dist /app/dist
|
|
||||||
# copy the prod dependencies (node_modules) from the prod-deps image
|
|
||||||
COPY --from=prod-deps /app/node_modules /app/node_modules
|
|
||||||
WORKDIR /app
|
|
||||||
# copy necessary files
|
|
||||||
COPY package.json ./
|
|
||||||
# open port 8000
|
|
||||||
EXPOSE 8000
|
|
||||||
# set default command
|
|
||||||
CMD ["yarn" ,"start"]
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# Discordeno Rest Proxy
|
|
||||||
|
|
||||||
[Benefits Of A Proxy](https://discordeno.js.org/docs/intro#rest)
|
|
||||||
|
|
||||||
## Setup Instructions
|
|
||||||
|
|
||||||
1. Ask Yui
|
|
||||||
2. Ask H0
|
|
||||||
3. Ask Itoh
|
|
||||||
4. Blame wolf
|
|
||||||
5. Ask Skillz
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "rest",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"build": "swc src --delete-dir-on-start --out-dir dist",
|
|
||||||
"start": "node ./dist/index.js"
|
|
||||||
},
|
|
||||||
"packageManager": "yarn@3.5.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@discordeno/rest": "latest",
|
|
||||||
"express": "^4.18.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@swc/cli": "^0.1.57",
|
|
||||||
"@swc/core": "^1.3.21",
|
|
||||||
"@types/express": "^4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import type { RequestMethods } from '@discordeno/rest'
|
|
||||||
import express from 'express'
|
|
||||||
import { REST } from './rest.js'
|
|
||||||
|
|
||||||
const AUTHORIZATION = process.env.AUTHORIZATION as string
|
|
||||||
|
|
||||||
const app = express()
|
|
||||||
|
|
||||||
app.use(
|
|
||||||
express.urlencoded({
|
|
||||||
extended: true,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
app.use(express.json())
|
|
||||||
|
|
||||||
app.all('/*', async (req, res) => {
|
|
||||||
if (!AUTHORIZATION || AUTHORIZATION !== req.headers.authorization) {
|
|
||||||
return res.status(401).json({ error: 'Invalid authorization key.' })
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
let url = req.originalUrl
|
|
||||||
if (url.startsWith('/v')) {
|
|
||||||
url = url.slice(url.indexOf('/', 2))
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await REST.makeRequest(req.method as RequestMethods, url, req.body)
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
res.status(200).json(result)
|
|
||||||
} else {
|
|
||||||
res.status(204).json()
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
console.log(error)
|
|
||||||
res.status(500).json(error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
app.listen(8000, () => {
|
|
||||||
console.log(`REST listening on port #8000`)
|
|
||||||
})
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import { createRestManager } from '@discordeno/rest'
|
|
||||||
|
|
||||||
export const REST = createRestManager({
|
|
||||||
token: process.env.TOKEN,
|
|
||||||
})
|
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user