Skip to content

Commit

Permalink
feat: first blood, should just work
Browse files Browse the repository at this point in the history
  • Loading branch information
JounQin committed Nov 3, 2023
1 parent 1770caf commit f29b943
Show file tree
Hide file tree
Showing 17 changed files with 15,342 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: CI

on:
- push
- pull_request

jobs:
ci:
name: Lint and Test with Node.js ${{ matrix.node }}
strategy:
matrix:
node:
- 18
- 20
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4

- name: Setup Node.js ${{ matrix.node }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: yarn

- name: Install Dependencies
run: yarn --immutable

- name: Build and Lint
run: yarn run-s build lint
env:
EFF_NO_LINK_RULES: true
PARSER_NO_WATCH: true
42 changes: 42 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: CodeQL

on:
push:
branches:
- main
pull_request:
schedule:
- cron: '5 3 * * 5'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language:
- javascript

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
queries: +security-and-quality

- name: Autobuild
uses: github/codeql-action/autobuild@v2

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: '/language:${{ matrix.language }}'
30 changes: 30 additions & 0 deletions .github/workflows/vercel.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Vercel Deploy

on:
push:
branches:
- main
pull_request:

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Check Branch
id: branch
if: ${{ github.ref == 'refs/heads/main' }}
run: |
echo "::set-output name=args::--prod"
echo "::set-output name=comment::false"
- name: Deploy
uses: amondnet/vercel-action@v25
with:
vercel-args: ${{ steps.branch.outputs.args }}
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
github-comment: ${{ steps.branch.outputs.comment != 'false' }}
github-token: ${{ secrets.GITHUB_TOKEN }}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.*cache
.vercel
.yarn/*
!.yarn/plugins
node_modules
*.tsbuildinfo
/public/index.html
1 change: 1 addition & 0 deletions .lintstagedrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@1stg/lint-staged/tsc')
1 change: 1 addition & 0 deletions .simple-git-hooks.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@1stg/simple-git-hooks')
1 change: 1 addition & 0 deletions .yarn/plugins/plugin-prepare-lifecycle.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports={name:"plugin-prepare-lifecycle",factory:e=>({hooks:{afterAllInstalled(r){if(!r.topLevelWorkspace.manifest.scripts.get("prepare"))return;e("@yarnpkg/shell").execute("yarn prepare")}}})};
6 changes: 6 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
nodeLinker: node-modules

plugins:
- checksum: 37b2361b1502b2054e6779788c0e9bdd6a90ce49852a8cad2feda79b0614ec94f06fb6e78951f5f95429c610d7934dd077caa47413a0227378a102c55161616d
path: .yarn/plugins/plugin-prepare-lifecycle.cjs
spec: "https://github.com/un-es/yarn-plugin-prepare-lifecycle/releases/download/v0.0.1/index.js"
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,41 @@
# rabbit-linker

Stable link that redirects to random resource download link via Vercel.

## Usage

`https://rabbit-linker.vercel.app/{vendor}/{app}/{version}`

## Examples

The followings version and short version are both fine.

- <https://rabbit-linker.vercel.app/gtimg/sogou_mac/1688992049>
- <https://rabbit-linker.vercel.app/gtimg/sogou_mac/614d>

## Sponsors

| 1stG | RxTS | UnTS |
| ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| [![1stG Open Collective backers and sponsors](https://opencollective.com/1stG/organizations.svg)](https://opencollective.com/1stG) | [![RxTS Open Collective backers and sponsors](https://opencollective.com/rxts/organizations.svg)](https://opencollective.com/rxts) | [![UnTS Open Collective backers and sponsors](https://opencollective.com/unts/organizations.svg)](https://opencollective.com/unts) |

## Backers

[![Backers](https://raw.githubusercontent.com/1stG/static/master/sponsors.svg)](https://github.com/sponsors/JounQin)

| 1stG | RxTS | UnTS |
| -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| [![1stG Open Collective backers and sponsors](https://opencollective.com/1stG/individuals.svg)](https://opencollective.com/1stG) | [![RxTS Open Collective backers and sponsors](https://opencollective.com/rxts/individuals.svg)](https://opencollective.com/rxts) | [![UnTS Open Collective backers and sponsors](https://opencollective.com/unts/individuals.svg)](https://opencollective.com/unts) |

## License

[MIT][] © [JounQin][]@[1stG.me][]

## Sponsorship

[![Vercel](https://images.ctfassets.net/e5382hct74si/78Olo8EZRdUlcDUFQvnzG7/fa4cdb6dc04c40fceac194134788a0e2/1618983297-powered-by-vercel.svg)](https://vercel.com/guides/can-vercel-sponsor-my-open-source-project?utm_source=1stG&utm_campaign=oss)

[1stg.me]: https://www.1stg.me
[app center]: https://appcenter.ms
[jounqin]: https://GitHub.com/JounQin
[mit]: http://opensource.org/licenses/MIT
1 change: 1 addition & 0 deletions api/[vendor]/[app].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './[app]/[version].js'
57 changes: 57 additions & 0 deletions api/[vendor]/[app]/[version].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { VercelRequest, VercelResponse } from '@vercel/node'
import { chromium } from 'playwright'

const BAD_REQUEST = 400

const INTERNAL_SERVER_ERROR = 500

// https://ime-sec.gtimg.com/202311032255/c2d34d57b6d7f9fc6b7869423e8576c2/pc/dl/gzindex/1688992049/sogou_mac_614d.zip
const DOWNLOAD_URL_REGEX =
/https:\/\/ime-sec\.gtimg.com\/\d+\/\w+\/pc\/dl\/gzindex\/(\d+)\/sogou_mac_(\w+)\.zip/

export default async (req: VercelRequest, res: VercelResponse) => {
const { vendor, app, version } = req.query as {
vendor: string
app: string
version?: string
}

if (vendor !== 'gtimg') {
res.writeHead(BAD_REQUEST)
res.write('Unsupported vendor yet')
return res.end()
}

if (app !== 'sogou_mac') {
res.writeHead(BAD_REQUEST)
res.write('Unsupported app yet')
return res.end()
}

const browser = await chromium.launch()
const page = await browser.newPage()
const result = await page.goto('https://pinyin.sogou.com/mac/')
const text = await result!.text()

const matched = text.match(DOWNLOAD_URL_REGEX)

if (!matched) {
res.writeHead(INTERNAL_SERVER_ERROR)
res.write(
'No download url found, please raise an issue to us: https://github.com/un-ts/rabbit-linker/issues/new',
)
return res.end()
}

const [url, timestamp, shortVersion] = matched

if (!version || [timestamp, shortVersion].includes(version)) {
return res.redirect(url)
}

res.writeHead(BAD_REQUEST)
res.write(
`No matched version found, it could be not the latest version, maybe you want version \`${shortVersion}\` instead`,
)
res.end()
}
54 changes: 54 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"name": "rabbit-linker",
"version": "0.1.0",
"type": "module",
"description": "Stable link that redirects to random resource download link via Vercel.",
"repository": "[email protected]:un-ts/rabbit-linker.git",
"author": "JounQin <[email protected]>",
"license": "MIT",
"private": true,
"packageManager": "[email protected]",
"scripts": {
"build": "playwright install --with-deps chromium && tsx scripts/build",
"lint": "run-p 'lint:*'",
"lint:es": "eslint . --cache",
"lint:tsc": "tsc --noEmit",
"prepare": "simple-git-hooks",
"start": "vc dev"
},
"dependencies": {
"playwright": "^1.39.0"
},
"devDependencies": {
"@1stg/common-config": "^9.0.0",
"@octokit/request": "^8.1.4",
"@types/web": "^0.0.119",
"commitlint": "^18.2.0",
"eslint": "^8.52.0",
"lint-staged": "^13.3.0",
"npm-run-all": "^4.1.5",
"simple-git-hooks": "^2.9.0",
"tsx": "^3.14.0",
"typescript": "^5.2.2",
"vercel": "^32.5.0"
},
"resolutions": {
"prettier": "^2.8.8"
},
"commitlint": {
"extends": "@1stg"
},
"eslintConfig": {
"extends": "@1stg"
},
"eslintIgnore": [
"/public/index.html",
"!/.*.js"
],
"prettier": "@1stg/prettier-config",
"renovate": {
"extends": [
"@1stg"
]
}
}
Binary file added public/favicon.ico
Binary file not shown.
50 changes: 50 additions & 0 deletions scripts/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import fs from 'node:fs/promises'

import { request } from '@octokit/request'

/**
* @link https://github.com/sindresorhus/github-markdown-css
*/
const { data } = await request('POST /markdown', {
text: await fs.readFile('README.md', 'utf8'),
token: process.env.GITHUB_TOKEN,
})

await fs.writeFile(
'public/index.html',
/* HTML */ `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>App Center</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/4.0.0/github-markdown.min.css"
/>
<style>
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
}
@media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
}
</style>
</head>
<body>
<article class="markdown-body">${data}</article>
</body>
</html>
`,
)
6 changes: 6 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "@1stg/tsconfig/nodenext",
"compilerOptions": {
"module": "NodeNext"
}
}
9 changes: 9 additions & 0 deletions vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"rewrites": [
{
"source": "/(.+)",
"destination": "/api/$1"
}
]
}
Loading

0 comments on commit f29b943

Please sign in to comment.