Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions .github/workflows/Lark-notification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ jobs:

- name: Event Message serialization
id: message
env:
GITHUB_CONTEXT: ${{ toJSON(github) }}
run: |
YAML=$(
cat <<JSON | deno run --allow-all .github/scripts/transform-message.ts
${{ toJSON(github) }}
JSON
)
YAML=$(printf '%s' "$GITHUB_CONTEXT" | deno run --allow-all .github/scripts/transform-message.ts)
{
echo 'content<<EOF'
echo "$YAML"
Expand Down
44 changes: 8 additions & 36 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,17 @@ jobs:
- uses: actions/checkout@v6
if: ${{ env.VERCEL_TOKEN && env.VERCEL_ORG_ID && env.VERCEL_PROJECT_ID }}

- uses: actions/setup-node@v6
if: ${{ env.VERCEL_TOKEN && env.VERCEL_ORG_ID && env.VERCEL_PROJECT_ID }}
with:
node-version: 24

- name: Deploy to Vercel
id: vercel-deployment
if: ${{ env.VERCEL_TOKEN && env.VERCEL_ORG_ID && env.VERCEL_PROJECT_ID }}
shell: bash
run: |
set -euo pipefail

npm install vercel -g

if [[ "$GITHUB_REF" == 'refs/heads/main' ]]; then
DeployOutput=$(vercel -t "$VERCEL_TOKEN" --prod)
else
DeployOutput=$(vercel -t "$VERCEL_TOKEN")
fi
echo "$DeployOutput"

ParsedURL=$(echo "$DeployOutput" | grep -Eo 'https://[^[:space:]]*\.vercel\.app' | tail -n 1)

if [[ -z "$ParsedURL" ]]; then
echo "Failed to parse Vercel URL from deploy output"
exit 1
fi
vercel inspect "$ParsedURL" -t "$VERCEL_TOKEN" -F json > vercel-inspect.json

InspectURL=$(jq -r '.url // empty' vercel-inspect.json)

if [[ -z "$InspectURL" ]]; then
echo "Failed to parse inspect url from vercel-inspect.json"
exit 1
fi
if [[ "$InspectURL" != http* ]]; then
InspectURL="https://$InspectURL"
fi
echo "preview-url=$InspectURL" >> "$GITHUB_OUTPUT"
uses: amondnet/vercel-action@v42.3.0
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
working-directory: ./
vercel-args: ${{ github.ref == 'refs/heads/main' && ' --prod' || '' }}

- name: Lark notification
uses: Open-Source-Bazaar/feishu-action@v3
Expand Down
155 changes: 155 additions & 0 deletions components/GitDiffView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { generateDiffFile } from '@git-diff-view/file';
import { DiffModeEnum, DiffView } from '@git-diff-view/react';
import { Icon } from 'idea-react';
import { computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import { ObservedComponent } from 'mobx-react-helper';
import { Alert, Button, ButtonGroup, Form } from 'react-bootstrap';

export interface TextFileData {
fileName: string;
content: string;
language?: string;
}

export type GitDiffViewProps = Record<'oldFile' | 'newFile', TextFileData>;

@observer
export class GitDiffView extends ObservedComponent<GitDiffViewProps> {
@observable
accessor diffViewMode = DiffModeEnum.Split;

@observable
accessor diffViewWrap = false;

@observable
accessor diffViewHighlight = true;

@observable
accessor expandAll = false;

@computed
get hasNoDiff() {
const { oldFile, newFile } = this.observedProps;

return oldFile.content === newFile.content;
}

@computed
get diffFile() {
const { oldFile, newFile } = this.observedProps;
const { diffViewMode, expandAll } = this;

const file = generateDiffFile(
oldFile.fileName,
oldFile.content,
newFile.fileName,
newFile.content,
oldFile.language || 'text',
newFile.language || 'text',
);
file.init();

if (diffViewMode & DiffModeEnum.Split) {
file.buildSplitDiffLines();
} else {
file.buildUnifiedDiffLines();
}
if (expandAll)
file.onAllExpand(diffViewMode & DiffModeEnum.Split ? 'split' : 'unified');

return file;
}

renderDiff() {
const {
diffViewMode,
diffViewWrap,
diffViewHighlight,
expandAll,
diffFile,
} = this;
Comment thread
TechQuery marked this conversation as resolved.

return (
<>
<div className="d-flex flex-wrap align-items-center gap-2 mb-3">
<ButtonGroup size="sm" aria-label="Diff mode">
<Button
variant={
diffViewMode & DiffModeEnum.Split
? 'primary'
: 'outline-primary'
}
onClick={() => (this.diffViewMode = DiffModeEnum.Split)}
>
<Icon name="layout-split" />
</Button>
<Button
variant={
diffViewMode & DiffModeEnum.Split
? 'outline-primary'
: 'primary'
}
onClick={() => (this.diffViewMode = DiffModeEnum.Unified)}
>
<Icon name="list-ul" />
</Button>
</ButtonGroup>

<Form.Check
type="switch"
id="git-diff-wrap"
label={<Icon name="text-wrap" />}
checked={diffViewWrap}
onChange={({ currentTarget }) =>
(this.diffViewWrap = currentTarget.checked)
}
/>
<Form.Check
type="switch"
id="git-diff-highlight"
label={<Icon name="highlighter" />}
checked={diffViewHighlight}
onChange={({ currentTarget }) =>
(this.diffViewHighlight = currentTarget.checked)
}
/>
<Form.Check
type="switch"
id="git-diff-expand-all"
label={<Icon name="arrows-expand" />}
checked={expandAll}
onChange={({ currentTarget }) =>
(this.expandAll = currentTarget.checked)
}
/>
</div>

<link
rel="stylesheet"
href="https://unpkg.com/@git-diff-view/react/styles/diff-view.css"
/>
<DiffView
diffFile={diffFile}
diffViewMode={diffViewMode}
diffViewWrap={diffViewWrap}
diffViewHighlight={diffViewHighlight}
/>
</>
);
}

render() {
const { hasNoDiff, props } = this;

return hasNoDiff ? (
<>
<Alert variant="danger">No diff found between the two files.</Alert>

<pre>{props.oldFile.content}</pre>
</>
) : (
this.renderDiff()
);
}
}
1 change: 0 additions & 1 deletion eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export default defineConfig(
'simple-import-sort': simpleImportSortPlugin,
'@typescript-eslint': tsEslint.plugin,
react,
// @ts-expect-error https://github.com/vercel/next.js/discussions/84792
'@next/next': nextPlugin,
},
},
Expand Down
81 changes: 37 additions & 44 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,101 +8,94 @@
},
"dependencies": {
"@editorjs/code": "^2.9.4",
"@editorjs/editorjs": "^2.31.5",
"@editorjs/header": "^2.8.8",
"@editorjs/editorjs": "^2.31.6",
"@editorjs/header": "^2.8.9",
"@editorjs/image": "^2.10.3",
"@editorjs/link": "^2.6.2",
"@editorjs/list": "^2.0.9",
"@editorjs/paragraph": "^2.11.7",
"@editorjs/quote": "^2.7.6",
"@git-diff-view/file": "^0.1.5",
"@git-diff-view/react": "^0.1.5",
"@mdx-js/loader": "^3.1.1",
"@mdx-js/react": "^3.1.1",
"@next/mdx": "^16.2.2",
"@sentry/nextjs": "^10.47.0",
"@next/mdx": "^16.2.9",
"@sentry/nextjs": "^10.57.0",
"copy-webpack-plugin": "^14.0.0",
"core-js": "^3.49.0",
"editorjs-html": "^4.0.5",
"file-type": "^22.0.0",
"file-type": "^22.0.1",
"formidable": "^3.5.4",
"idea-react": "^2.0.0-rc.13",
"idea-react": "^2.2.2",
"jsonwebtoken": "^9.0.3",
"koa": "^3.2.0",
"koa": "^3.2.1",
"koa-jwt": "^4.0.4",
"koajax": "^3.3.0",
"less": "^4.6.4",
"less-loader": "^12.3.2",
"less-loader": "^13.0.0",
"lodash": "^4.18.1",
"marked": "^17.0.6",
"marked": "^18.0.5",
"mime": "^4.1.0",
"mobx": "^6.15.0",
"mobx": "^6.16.1",
"mobx-github": "^0.6.2",
"mobx-i18n": "^0.7.2",
"mobx-lark": "^2.8.1",
"mobx-react": "^9.2.1",
"mobx-react": "^9.2.2",
"mobx-react-helper": "^0.5.1",
"mobx-restful": "^2.1.4",
"mobx-restful-table": "^2.6.3",
"next": "^16.2.2",
"next": "^16.2.9",
"next-pwa": "~5.6.0",
"next-ssr-middleware": "^1.1.0",
"next-with-less": "^3.0.1",
"prismjs": "^1.30.0",
"react": "^19.2.4",
"react": "^19.2.7",
"react-bootstrap": "^2.10.10",
"react-bootstrap-editor": "^2.1.1",
"react-dom": "^19.2.4",
"react-dom": "^19.2.7",
"react-editor-js": "^2.1.0",
"remark-frontmatter": "^5.0.0",
"remark-gfm": "^4.0.1",
"remark-mdx-frontmatter": "^5.2.0",
"undici": "^8.0.2",
"web-utility": "^4.6.5",
"webpack": "^5.105.4",
"yaml": "^2.8.3"
"undici": "^8.4.1",
"web-utility": "^4.6.6",
"webpack": "^5.107.2",
"yaml": "^2.9.0"
},
"devDependencies": {
"@babel/plugin-proposal-decorators": "^7.29.0",
"@babel/plugin-transform-typescript": "^7.28.6",
"@babel/preset-react": "^7.28.5",
"@cspell/eslint-plugin": "^10.0.0",
"@babel/plugin-proposal-decorators": "^7.29.7",
"@babel/plugin-transform-typescript": "^7.29.7",
"@babel/preset-react": "^7.29.7",
"@cspell/eslint-plugin": "^10.0.1",
"@eslint/js": "^10.0.1",
"@next/eslint-plugin-next": "^16.2.2",
"@next/eslint-plugin-next": "^16.2.9",
"@softonus/prettier-plugin-duplicate-remover": "^1.1.2",
"@stylistic/eslint-plugin": "^5.10.0",
"@types/eslint-config-prettier": "^6.11.3",
"@types/formidable": "^3.5.0",
"@types/formidable": "^3.5.1",
"@types/jsonwebtoken": "^9.0.10",
"@types/koa": "^3.0.2",
"@types/koa": "^3.0.3",
"@types/lodash": "^4.17.24",
"@types/next-pwa": "^5.6.9",
"@types/node": "^24.12.2",
"@types/react": "^19.2.14",
"eslint": "^10.2.0",
"eslint-config-next": "^16.2.2",
"@types/node": "^24.13.2",
"@types/react": "^19.2.17",
"eslint": "^10.5.0",
"eslint-config-next": "^16.2.9",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-simple-import-sort": "^12.1.1",
"globals": "^17.4.0",
"eslint-plugin-simple-import-sort": "^13.0.0",
"globals": "^17.6.0",
"husky": "^9.1.7",
"jiti": "^2.6.1",
"lint-staged": "^16.4.0",
"prettier": "^3.8.1",
"jiti": "^2.7.0",
"lint-staged": "^17.0.7",
"prettier": "^3.8.4",
"prettier-plugin-css-order": "^2.2.0",
"typescript": "~5.9.3",
"typescript-eslint": "^8.58.0"
"typescript-eslint": "^8.61.0"
},
"resolutions": {
"next": "$next"
},
"pnpm": {
"onlyBuiltDependencies": [
"@sentry/cli",
"core-js",
"less",
"sharp",
"unrs-resolver"
]
},
"prettier": {
"singleQuote": true,
"trailingComma": "all",
Expand Down
7 changes: 2 additions & 5 deletions pages/api/Lark/file/[id]/[name].ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Middleware } from 'koa';
import MIME from 'mime';
import { createKoaRouter, withKoaRouter } from 'next-ssr-middleware';
import { Readable } from 'stream';
import { parseJSON } from 'web-utility';

import { CACHE_HOST } from '../../../../../models/configuration';
import { safeAPI } from '../../../core';
Expand Down Expand Up @@ -31,11 +32,7 @@ const downloader: Middleware = async context => {
if (!ok) {
context.status = status;

try {
return (context.body = await response.json());
} catch {
return (context.body = await response.text());
}
return (context.body = parseJSON(await response.text()));
}
const mime = headers.get('Content-Type'),
[stream1, stream2] = body!.tee();
Expand Down
Loading
Loading