diff --git a/.changelogrc.js b/.changelogrc.js new file mode 100644 index 0000000..9a2f5f9 --- /dev/null +++ b/.changelogrc.js @@ -0,0 +1 @@ +module.exports = require('@lobehub/lint').changelog; diff --git a/.commitlintrc.js b/.commitlintrc.js new file mode 100644 index 0000000..9b8c6ac --- /dev/null +++ b/.commitlintrc.js @@ -0,0 +1 @@ +module.exports = require('@lobehub/lint').commitlint; diff --git a/.dumirc.ts b/.dumirc.ts new file mode 100644 index 0000000..b0981c2 --- /dev/null +++ b/.dumirc.ts @@ -0,0 +1,47 @@ +import { defineConfig } from 'dumi'; +import { Github } from 'lucide-react'; + +import { homepage } from './package.json'; + +const themeConfig = { + actions: [ + { + icon: Github, + link: homepage, + openExternal: true, + text: 'Github', + }, + { + link: '/components/action-icon', + text: 'Get Started', + type: 'primary', + }, + ], + footer: 'Made with 🤯 by LobeHub', + name: 'Realtime Weather', + socialLinks: { + discord: 'https://discord.gg/AYFPHvv2jT', + github: homepage, + }, +}; + +export default defineConfig({ + extraBabelPlugins: ['babel-plugin-antd-style'], + favicons: [ + 'https://registry.npmmirror.com/@lobehub/assets-emoji/1.3.0/files/assets/rainbow.webp', + ], + // locales: [{ id: 'en-US', name: 'English' }], + mfsu: {}, + npmClient: 'pnpm', + outputPath: 'docs-dist', + // ssr: isProduction ? {} : false, + styles: [ + `html, body { background: transparent; } + + @media (prefers-color-scheme: dark) { + html, body { background: #000; } + }`, + ], + themeConfig, + title: 'RealTime Weather - Lobe Chat Plugin', +}); diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7e3649a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..8336e93 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,8 @@ +/lambda/ +/scripts +/config +.history +public +dist +.umi +mock \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..afaf303 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,3 @@ +const config = require('@lobehub/lint').eslint; + +module.exports = config; diff --git a/.fatherrc.ts b/.fatherrc.ts new file mode 100644 index 0000000..52193e5 --- /dev/null +++ b/.fatherrc.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'father'; + +export default defineConfig({ + umd: { + output: { path: 'dist', filename: 'index' }, + externals: { + 'react': 'React', + 'react-dom': 'ReactDOM', + 'antd': 'antd', + 'antd-style': 'antd-style', + }, + + chainWebpack: (memo) => { + // use https://github.com/systemjs/systemjs to dynamic load + memo.output.libraryTarget('system'); + return memo; + }, + }, +}); diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e764a29 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,60 @@ +name: Release CI +on: + push: + branches: + - master + - alpha + - beta + - rc + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Setup Node.js environment + uses: actions/setup-node@v3 + with: + node-version: '18' + + - name: Install deps + run: pnpm install + + - name: lint + run: pnpm run lint && pnpm run doctor + + - name: Test + run: pnpm run test + + release: + needs: test + name: Release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Setup Node.js environment + uses: actions/setup-node@v3 + with: + node-version: '18' + + - name: Install deps + run: pnpm install + + - name: release + run: pnpm run release + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..b2f683f --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,28 @@ +name: Test +on: [push] + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Setup Node.js environment + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Install deps + run: pnpm install + + - name: Test and coverage + run: pnpm run test:coverage + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1cfc09 --- /dev/null +++ b/.gitignore @@ -0,0 +1,44 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +**/node_modules +# roadhog-api-doc ignore +/src/utils/request-temp.js +_roadhog-api-doc + +# production +/dist +/.vscode + +# misc +.DS_Store +npm-debug.log* +yarn-error.log + +/coverage +.idea +package-lock.json +*bak +.vscode + +# visual studio code +.history +*.log +functions/* +.temp/** + +# umi +.umi +.umi-production + +# screenshot +screenshot +.firebase +.eslintcache + +build + +.env + +.vercel +.next diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000..c160a77 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npx --no -- commitlint --edit ${1} diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..cf0c46b --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npx --no-install lint-staged diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..d9ed3d3 --- /dev/null +++ b/.npmrc @@ -0,0 +1,11 @@ +lockfile=false +resolution-mode=highest +public-hoist-pattern[]=*@umijs/lint* +public-hoist-pattern[]=*changelog* +public-hoist-pattern[]=*commitlint* +public-hoist-pattern[]=*eslint* +public-hoist-pattern[]=*postcss* +public-hoist-pattern[]=*prettier* +public-hoist-pattern[]=*remark* +public-hoist-pattern[]=*semantic-release* +public-hoist-pattern[]=*stylelint* diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..a039fc2 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,23 @@ +**/*.svg +**/*.ejs +.umi +.umi-production +/dist +.dockerignore +.DS_Store +.eslintignore +*.png +*.toml +docker +.editorconfig +Dockerfile* +.gitignore +.prettierignore +LICENSE +.eslintcache +*.lock +yarn-error.log +.history +CNAME +/build +/public diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..f0355a9 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1 @@ +module.exports = require('@lobehub/lint').prettier; diff --git a/.releaserc.js b/.releaserc.js new file mode 100644 index 0000000..3793001 --- /dev/null +++ b/.releaserc.js @@ -0,0 +1 @@ +module.exports = require('@lobehub/lint').semanticRelease; diff --git a/.remarkrc.js b/.remarkrc.js new file mode 100644 index 0000000..b673c10 --- /dev/null +++ b/.remarkrc.js @@ -0,0 +1 @@ +module.exports = require('@lobehub/lint').remarklint; diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1dd53d2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 LobeHub + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1b6db1c --- /dev/null +++ b/README.md @@ -0,0 +1,170 @@ + + +
+ + + + + +

LobeChat Plugin Template

+ +LobeChat 插件开发模板 + +[Changelog](./CHANGELOG.md) · [Report Bug][issues-url] · [Request Feature][issues-url] + + + +[![plugin][plugin-shield]][plugin-url] +[![release][release-shield]][release-url] +[![releaseDate][release-date-shield]][release-date-url] +[![ciTest][ci-test-shield]][ci-test-url] +[![ciRelease][ci-release-shield]][ci-release-url]
+[![contributors][contributors-shield]][contributors-url] +[![forks][forks-shield]][forks-url] +[![stargazers][stargazers-shield]][stargazers-url] +[![issues][issues-shield]][issues-url] + +![](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png) + +
+ +
+Table of contents + +#### TOC + +- [📦 Installation](#-installation) + +- [🤯 Usage](#-usage) + +- [⌨️ Local Development](#️-local-development) + +- [🤝 Contributing](#-contributing) + +#### + +
+ +## 📦 Installation + +TOBE DONE + +
+ +[![][back-to-top]](#readme-top) + +
+ +## 🤯 Usage + +
+ +[![][back-to-top]](#readme-top) + +
+ +## ⌨️ Local Development + +You can use Gitpod for online development: + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][gitpod-url] + +Or clone it for local development: + +```bash +$ git clone https://github.com/lobehub/chat-plugin-template.git +$ cd chat-plugin-template +$ pnpm install +$ pnpm run dev +``` + +
+ +[![][back-to-top]](#readme-top) + +
+ +## 🤝 Contributing + + + +> 📊 Total: **3** + + + + + + + + + + + + + +
+ +[![][back-to-top]](#readme-top) + +
+ +--- + +#### 📝 License + +Copyright © 2023 [LobeHub][profile-url].
+This project is [MIT](./LICENSE) licensed. + + + +[plugin-shield]: https://img.shields.io/badge/%F0%9F%A4%AF_LobeChat-plugin-cyan +[plugin-url]: https://github.com/lobehub/lobe-chat-plugins + + + +[profile-url]: https://github.com/lobehub +[gitpod-url]: https://gitpod.io/#https://github.com/lobehub/chat-plugin-template + + + +[back-to-top]: https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square + + + +[release-shield]: https://img.shields.io/npm/v/@lobehub/chat-plugin-template?label=%F0%9F%A4%AF%20NPM +[release-url]: https://www.npmjs.com/package/@lobehub/chat-plugin-template + + + +[release-date-shield]: https://img.shields.io/github/release-date/lobehub/chat-plugin-template?style=flat +[release-date-url]: https://github.com/lobehub/chat-plugin-template/releases + + + +[ci-test-shield]: https://github.com/lobehub/chat-plugin-template/actions/workflows/test.yml/badge.svg +[ci-test-url]: https://github.com/lobehub/chat-plugin-template/actions/workflows/test.yml + + + +[ci-release-shield]: https://github.com/lobehub/chat-plugin-template/actions/workflows/release.yml/badge.svg +[ci-release-url]: https://github.com/lobehub/chat-plugin-template/actions/workflows/release.yml + + + +[contributors-shield]: https://img.shields.io/github/contributors/lobehub/chat-plugin-template.svg?style=flat +[contributors-url]: https://github.com/lobehub/chat-plugin-template/graphs/contributors + + + +[forks-shield]: https://img.shields.io/github/forks/lobehub/chat-plugin-template.svg?style=flat +[forks-url]: https://github.com/lobehub/chat-plugin-template/network/members + + + +[stargazers-shield]: https://img.shields.io/github/stars/lobehub/chat-plugin-template.svg?style=flat +[stargazers-url]: https://github.com/lobehub/chat-plugin-template/stargazers + + + +[issues-shield]: https://img.shields.io/github/issues/lobehub/chat-plugin-template.svg?style=flat +[issues-url]: https://github.com/lobehub/chat-plugin-template/issues/new/choose diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..4f11a03 --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/next.config.mjs b/next.config.mjs new file mode 100644 index 0000000..55368fb --- /dev/null +++ b/next.config.mjs @@ -0,0 +1,25 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, + crossOrigin: 'anonymous', + async headers() { + return [ + { + // matching all API routes + source: '/:path*', + headers: [ + { key: 'Access-Control-Allow-Credentials', value: 'true' }, + { key: 'Access-Control-Allow-Origin', value: '*' }, + { key: 'Access-Control-Allow-Methods', value: 'GET,OPTIONS,PATCH,DELETE,POST,PUT' }, + { + key: 'Access-Control-Allow-Headers', + value: + 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version', + }, + ], + }, + ]; + }, +}; + +export default nextConfig; diff --git a/package.json b/package.json new file mode 100644 index 0000000..235c4df --- /dev/null +++ b/package.json @@ -0,0 +1,67 @@ +{ + "name": "@lobehub/chat-plugin-template", + "version": "0.0.0", + "private": true, + "description": "Lobe Chat Plugin Template", + "homepage": "https://github.com/lobehub/chat-plugin-template", + "repository": "https://github.com/lobehub/chat-plugin-template.git", + "scripts": { + "build": "next build", + "ci": "npm run lint && npm run type-check", + "dev": "next dev -p 3400", + "lint": "npm run lint:js && npm run lint:prettier", + "lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ", + "lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx src/pages/api", + "lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx src/pages/api", + "lint:prettier": "prettier --check \\\"src/pages/api/**/*\\\" --end-of-line auto", + "prepare": "husky install", + "prepublishOnly": "npm run doctor && npm run build", + "prettier": "prettier -c --write \\\"src/pages/api/**/*\\\"", + "release": "semantic-release", + "start": "next start", + "test": "vitest --passWithNoTests", + "test:coverage": "vitest --coverage --passWithNoTests", + "type-check": "tsc --noEmit" + }, + "lint-staged": { + "**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js", + "**/*.{js,jsx,tsx,ts,less,md,json}": [ + "prettier --write" + ] + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 10" + ], + "dependencies": { + "@lobehub/chat-plugin-sdk": "^1", + "@lobehub/chat-plugins-gateway": "^1", + "@types/react": "18.2.21", + "@types/react-dom": "18.2.7", + "antd": "^5", + "next": "^13.4.19", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-layout-kit": "^1" + }, + "devDependencies": { + "@lobehub/lint": "latest", + "@lobehub/ui": "latest", + "@vercel/node": "^2", + "@vitest/coverage-v8": "latest", + "babel-plugin-antd-style": "^1.0.4", + "commitlint": "^17", + "cross-env": "^7", + "eslint": "^8", + "father": "^4.3.1", + "husky": "^8", + "lint-staged": "^13", + "lucide-react": "latest", + "prettier": "^3", + "semantic-release": "^21", + "typescript": "^5", + "vercel": "^32", + "vitest": "latest" + } +} diff --git a/public/manifest-dev.json b/public/manifest-dev.json new file mode 100644 index 0000000..be509c4 --- /dev/null +++ b/public/manifest-dev.json @@ -0,0 +1,27 @@ +{ + "identifier": "chat-plugin-template", + "version": "1", + "api": [ + { + "url": "http://localhost:3400/api/v1", + "name": "greetUser", + "description": "当用户说出 hello 后,你需要问候用户,并祝他开心", + "parameters": { + "properties": { + "nickname": { + "description": "用户的名字,例如:张三 等", + "type": "string" + } + }, + "required": [ + "nickname" + ], + "type": "object" + } + } + ], + "gateway": "http://localhost:3400/api/gateway", + "ui": { + + } +} diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..341464d --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,26 @@ +{ + "identifier": "chat-plugin-template", + "version": "1", + "api": [ + { + "url": "https://template.chat-plugin.lobehub.com/api/v1", + "name": "hello", + "description": "问候用户,当用户说出 hello plugin 后,将会调用该方法,并将结果返回给用户", + "parameters": { + "properties": { + "city": { + "description": "城市名称", + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + } + ], + "ui": { + "url": "https://registry.npmmirror.com/@lobehub/chat-plugin-template/latest/files" + } +} diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx new file mode 100644 index 0000000..da826ed --- /dev/null +++ b/src/pages/_app.tsx @@ -0,0 +1,5 @@ +import type { AppProps } from 'next/app'; + +export default function App({ Component, pageProps }: AppProps) { + return ; +} diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx new file mode 100644 index 0000000..af2f1ab --- /dev/null +++ b/src/pages/_document.tsx @@ -0,0 +1,13 @@ +import { Head, Html, Main, NextScript } from 'next/document'; + +export default function Document() { + return ( + + + +
+ + + + ); +} diff --git a/src/pages/api/gateway.ts b/src/pages/api/gateway.ts new file mode 100644 index 0000000..12facf5 --- /dev/null +++ b/src/pages/api/gateway.ts @@ -0,0 +1,13 @@ +import { createLobeChatPluginGateway } from '@lobehub/chat-plugins-gateway'; + +export const config = { + runtime: 'edge', +}; + +export default async (req: Request) => { + if (process.env.NODE_ENV === 'development') { + return createLobeChatPluginGateway()(req); + } + + return; +}; diff --git a/src/pages/api/v1/index.ts b/src/pages/api/v1/index.ts new file mode 100644 index 0000000..f23a65b --- /dev/null +++ b/src/pages/api/v1/index.ts @@ -0,0 +1,15 @@ +import { PluginErrorType, createErrorResponse } from '@lobehub/chat-plugin-sdk'; + +export const config = { + runtime: 'edge', +}; + +export default async (req: Request) => { + if (req.method !== 'POST') return createErrorResponse(PluginErrorType.MethodNotAllowed); + + const args = await req.json(); + + const result = { hello: args }; + + return new Response(JSON.stringify(result)); +}; diff --git a/src/pages/index.tsx b/src/pages/index.tsx new file mode 100644 index 0000000..285b5ce --- /dev/null +++ b/src/pages/index.tsx @@ -0,0 +1,7 @@ +import { memo } from 'react'; + +const Render = memo(() => { + return
word
; +}); + +export default Render; diff --git a/src/type.ts b/src/type.ts new file mode 100644 index 0000000..38f75f5 --- /dev/null +++ b/src/type.ts @@ -0,0 +1,8 @@ +export interface WeatherParams { + city: string; + extensions?: 'base' | 'all'; +} + +export type ResponseResult = { + hello: string; +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6430179 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "target": "ES5", + "lib": ["esnext", "DOM"], + "sourceMap": true, + "skipDefaultLibCheck": true, + "jsx": "preserve", + "baseUrl": ".", + "types": ["node"], + "allowSyntheticDefaultImports": true, + "moduleResolution": "node", + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "paths": { + "@/*": ["src/*"] + }, + "allowJs": true, + "noEmit": true, + "incremental": true, + "esModuleInterop": true, + "isolatedModules": true + }, + "exclude": ["node_modules"], + "include": ["src", "next-env.d.ts"] +} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..014f97e --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + environment: 'node', + globals: true, + }, +});