瀏覽代碼

init: 初始化项目

jiaxing.liao 1 周之前
父節點
當前提交
3aba922beb
共有 89 個文件被更改,包括 7066 次插入1805 次删除
  1. 6 0
      .prettierignore
  2. 8 0
      .prettierrc.cjs
  3. 4 0
      .prettierrc.yaml
  4. 0 36
      apps/docs/.gitignore
  5. 0 36
      apps/docs/README.md
  6. 二進制
      apps/docs/app/favicon.ico
  7. 二進制
      apps/docs/app/fonts/GeistMonoVF.woff
  8. 二進制
      apps/docs/app/fonts/GeistVF.woff
  9. 0 50
      apps/docs/app/globals.css
  10. 0 31
      apps/docs/app/layout.tsx
  11. 0 186
      apps/docs/app/page.module.css
  12. 0 102
      apps/docs/app/page.tsx
  13. 0 4
      apps/docs/eslint.config.js
  14. 0 4
      apps/docs/next.config.js
  15. 0 28
      apps/docs/package.json
  16. 0 3
      apps/docs/public/file-text.svg
  17. 0 10
      apps/docs/public/globe.svg
  18. 0 1
      apps/docs/public/next.svg
  19. 0 19
      apps/docs/public/turborepo-dark.svg
  20. 0 19
      apps/docs/public/turborepo-light.svg
  21. 0 10
      apps/docs/public/vercel.svg
  22. 0 3
      apps/docs/public/window.svg
  23. 0 20
      apps/docs/tsconfig.json
  24. 21 33
      apps/web/.gitignore
  25. 3 0
      apps/web/.vscode/extensions.json
  26. 3 34
      apps/web/README.md
  27. 二進制
      apps/web/app/favicon.ico
  28. 二進制
      apps/web/app/fonts/GeistMonoVF.woff
  29. 二進制
      apps/web/app/fonts/GeistVF.woff
  30. 0 50
      apps/web/app/globals.css
  31. 0 31
      apps/web/app/layout.tsx
  32. 0 186
      apps/web/app/page.module.css
  33. 0 102
      apps/web/app/page.tsx
  34. 0 4
      apps/web/eslint.config.js
  35. 13 0
      apps/web/index.html
  36. 0 4
      apps/web/next.config.js
  37. 17 18
      apps/web/package.json
  38. 0 3
      apps/web/public/file-text.svg
  39. 0 10
      apps/web/public/globe.svg
  40. 0 1
      apps/web/public/next.svg
  41. 0 19
      apps/web/public/turborepo-dark.svg
  42. 0 19
      apps/web/public/turborepo-light.svg
  43. 0 10
      apps/web/public/vercel.svg
  44. 1 0
      apps/web/public/vite.svg
  45. 0 3
      apps/web/public/window.svg
  46. 30 0
      apps/web/src/App.vue
  47. 1 0
      apps/web/src/assets/vue.svg
  48. 41 0
      apps/web/src/components/HelloWorld.vue
  49. 5 0
      apps/web/src/main.ts
  50. 79 0
      apps/web/src/style.css
  51. 16 0
      apps/web/tsconfig.app.json
  52. 4 17
      apps/web/tsconfig.json
  53. 26 0
      apps/web/tsconfig.node.json
  54. 7 0
      apps/web/vite.config.ts
  55. 1 0
      packages/api-client/README.md
  56. 3 0
      packages/api-client/index.ts
  57. 19 0
      packages/api-client/package.json
  58. 332 0
      packages/api-client/request.ts
  59. 4 0
      packages/api-client/types.ts
  60. 27 0
      packages/api-service/README.md
  61. 1 0
      packages/api-service/index.ts
  62. 7 0
      packages/api-service/openapi2ts.config.ts
  63. 17 0
      packages/api-service/package.json
  64. 3503 0
      packages/api-service/schema.json
  65. 23 0
      packages/api-service/servers/api/audit.ts
  66. 84 0
      packages/api-service/servers/api/credential.ts
  67. 72 0
      packages/api-service/servers/api/execution.ts
  68. 24 0
      packages/api-service/servers/api/index.ts
  69. 123 0
      packages/api-service/servers/api/projects.ts
  70. 15 0
      packages/api-service/servers/api/sourceControl.ts
  71. 79 0
      packages/api-service/servers/api/tags.ts
  72. 643 0
      packages/api-service/servers/api/typings.d.ts
  73. 90 0
      packages/api-service/servers/api/user.ts
  74. 66 0
      packages/api-service/servers/api/variables.ts
  75. 190 0
      packages/api-service/servers/api/workflow.ts
  76. 6 0
      packages/api-service/tsconfig.json
  77. 0 57
      packages/eslint-config/next.js
  78. 36 0
      packages/eslint-config/vue.js
  79. 2 1
      packages/typescript-config/base.json
  80. 0 12
      packages/typescript-config/nextjs.json
  81. 3 0
      packages/typescript-config/package.json
  82. 8 0
      packages/typescript-config/vue.json
  83. 0 4
      packages/ui/eslint.config.mjs
  84. 0 26
      packages/ui/package.json
  85. 0 20
      packages/ui/src/button.tsx
  86. 0 27
      packages/ui/src/card.tsx
  87. 0 11
      packages/ui/src/code.tsx
  88. 0 8
      packages/ui/tsconfig.json
  89. 1403 533
      pnpm-lock.yaml

+ 6 - 0
.prettierignore

@@ -0,0 +1,6 @@
+out
+dist
+pnpm-lock.yaml
+LICENSE.md
+tsconfig.json
+tsconfig.*.json

+ 8 - 0
.prettierrc.cjs

@@ -0,0 +1,8 @@
+module.exports = {
+  singleQuote: true,
+  semi: false,
+  printWidth: 100,
+  trailingComma: none,
+  tabWidht: 2,
+  endOfLine: 'lf'
+}

+ 4 - 0
.prettierrc.yaml

@@ -0,0 +1,4 @@
+singleQuote: true
+semi: false
+printWidth: 100
+trailingComma: none

+ 0 - 36
apps/docs/.gitignore

@@ -1,36 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-.yarn/install-state.gz
-
-# testing
-/coverage
-
-# next.js
-/.next/
-/out/
-
-# production
-/build
-
-# misc
-.DS_Store
-*.pem
-
-# debug
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-# env files (can opt-in for commiting if needed)
-.env*
-
-# vercel
-.vercel
-
-# typescript
-*.tsbuildinfo
-next-env.d.ts

+ 0 - 36
apps/docs/README.md

@@ -1,36 +0,0 @@
-This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/create-next-app).
-
-## Getting Started
-
-First, run the development server:
-
-```bash
-npm run dev
-# or
-yarn dev
-# or
-pnpm dev
-# or
-bun dev
-```
-
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
-
-You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
-
-This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font.
-
-## Learn More
-
-To learn more about Next.js, take a look at the following resources:
-
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
-
-You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
-
-## Deploy on Vercel
-
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
-
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.

二進制
apps/docs/app/favicon.ico


二進制
apps/docs/app/fonts/GeistMonoVF.woff


二進制
apps/docs/app/fonts/GeistVF.woff


+ 0 - 50
apps/docs/app/globals.css

@@ -1,50 +0,0 @@
-:root {
-  --background: #ffffff;
-  --foreground: #171717;
-}
-
-@media (prefers-color-scheme: dark) {
-  :root {
-    --background: #0a0a0a;
-    --foreground: #ededed;
-  }
-}
-
-html,
-body {
-  max-width: 100vw;
-  overflow-x: hidden;
-}
-
-body {
-  color: var(--foreground);
-  background: var(--background);
-}
-
-* {
-  box-sizing: border-box;
-  padding: 0;
-  margin: 0;
-}
-
-a {
-  color: inherit;
-  text-decoration: none;
-}
-
-.imgDark {
-  display: none;
-}
-
-@media (prefers-color-scheme: dark) {
-  html {
-    color-scheme: dark;
-  }
-
-  .imgLight {
-    display: none;
-  }
-  .imgDark {
-    display: unset;
-  }
-}

+ 0 - 31
apps/docs/app/layout.tsx

@@ -1,31 +0,0 @@
-import type { Metadata } from "next";
-import localFont from "next/font/local";
-import "./globals.css";
-
-const geistSans = localFont({
-  src: "./fonts/GeistVF.woff",
-  variable: "--font-geist-sans",
-});
-const geistMono = localFont({
-  src: "./fonts/GeistMonoVF.woff",
-  variable: "--font-geist-mono",
-});
-
-export const metadata: Metadata = {
-  title: "Create Next App",
-  description: "Generated by create next app",
-};
-
-export default function RootLayout({
-  children,
-}: Readonly<{
-  children: React.ReactNode;
-}>) {
-  return (
-    <html lang="en">
-      <body className={`${geistSans.variable} ${geistMono.variable}`}>
-        {children}
-      </body>
-    </html>
-  );
-}

+ 0 - 186
apps/docs/app/page.module.css

@@ -1,186 +0,0 @@
-.page {
-  --gray-rgb: 0, 0, 0;
-  --gray-alpha-200: rgba(var(--gray-rgb), 0.08);
-  --gray-alpha-100: rgba(var(--gray-rgb), 0.05);
-
-  --button-primary-hover: #383838;
-  --button-secondary-hover: #f2f2f2;
-
-  display: grid;
-  grid-template-rows: 20px 1fr 20px;
-  align-items: center;
-  justify-items: center;
-  min-height: 100svh;
-  padding: 80px;
-  gap: 64px;
-  font-synthesis: none;
-}
-
-@media (prefers-color-scheme: dark) {
-  .page {
-    --gray-rgb: 255, 255, 255;
-    --gray-alpha-200: rgba(var(--gray-rgb), 0.145);
-    --gray-alpha-100: rgba(var(--gray-rgb), 0.06);
-
-    --button-primary-hover: #ccc;
-    --button-secondary-hover: #1a1a1a;
-  }
-}
-
-.main {
-  display: flex;
-  flex-direction: column;
-  gap: 32px;
-  grid-row-start: 2;
-}
-
-.main ol {
-  font-family: var(--font-geist-mono);
-  padding-left: 0;
-  margin: 0;
-  font-size: 14px;
-  line-height: 24px;
-  letter-spacing: -0.01em;
-  list-style-position: inside;
-}
-
-.main li:not(:last-of-type) {
-  margin-bottom: 8px;
-}
-
-.main code {
-  font-family: inherit;
-  background: var(--gray-alpha-100);
-  padding: 2px 4px;
-  border-radius: 4px;
-  font-weight: 600;
-}
-
-.ctas {
-  display: flex;
-  gap: 16px;
-}
-
-.ctas a {
-  appearance: none;
-  border-radius: 128px;
-  height: 48px;
-  padding: 0 20px;
-  font-family: var(--font-geist-sans);
-  border: 1px solid transparent;
-  transition: background 0.2s, color 0.2s, border-color 0.2s;
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-size: 16px;
-  line-height: 20px;
-  font-weight: 500;
-}
-
-a.primary {
-  background: var(--foreground);
-  color: var(--background);
-  gap: 8px;
-}
-
-a.secondary {
-  border-color: var(--gray-alpha-200);
-  min-width: 180px;
-}
-
-button.secondary {
-  appearance: none;
-  border-radius: 128px;
-  height: 48px;
-  padding: 0 20px;
-  font-family: var(--font-geist-sans);
-  border: 1px solid transparent;
-  transition: background 0.2s, color 0.2s, border-color 0.2s;
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-size: 16px;
-  line-height: 20px;
-  font-weight: 500;
-  background: transparent;
-  border-color: var(--gray-alpha-200);
-  min-width: 180px;
-}
-
-.footer {
-  font-family: var(--font-geist-sans);
-  grid-row-start: 3;
-  display: flex;
-  gap: 24px;
-}
-
-.footer a {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-}
-
-.footer img {
-  flex-shrink: 0;
-}
-
-/* Enable hover only on non-touch devices */
-@media (hover: hover) and (pointer: fine) {
-  a.primary:hover {
-    background: var(--button-primary-hover);
-    border-color: transparent;
-  }
-
-  a.secondary:hover {
-    background: var(--button-secondary-hover);
-    border-color: transparent;
-  }
-
-  .footer a:hover {
-    text-decoration: underline;
-    text-underline-offset: 4px;
-  }
-}
-
-@media (max-width: 600px) {
-  .page {
-    padding: 32px;
-    padding-bottom: 80px;
-  }
-
-  .main {
-    align-items: center;
-  }
-
-  .main ol {
-    text-align: center;
-  }
-
-  .ctas {
-    flex-direction: column;
-  }
-
-  .ctas a {
-    font-size: 14px;
-    height: 40px;
-    padding: 0 16px;
-  }
-
-  a.secondary {
-    min-width: auto;
-  }
-
-  .footer {
-    flex-wrap: wrap;
-    align-items: center;
-    justify-content: center;
-  }
-}
-
-@media (prefers-color-scheme: dark) {
-  .logo {
-    filter: invert();
-  }
-}

文件差異過大導致無法顯示
+ 0 - 102
apps/docs/app/page.tsx


+ 0 - 4
apps/docs/eslint.config.js

@@ -1,4 +0,0 @@
-import { nextJsConfig } from "@repo/eslint-config/next-js";
-
-/** @type {import("eslint").Linter.Config[]} */
-export default nextJsConfig;

+ 0 - 4
apps/docs/next.config.js

@@ -1,4 +0,0 @@
-/** @type {import('next').NextConfig} */
-const nextConfig = {};
-
-export default nextConfig;

+ 0 - 28
apps/docs/package.json

@@ -1,28 +0,0 @@
-{
-  "name": "docs",
-  "version": "0.1.0",
-  "type": "module",
-  "private": true,
-  "scripts": {
-    "dev": "next dev --port 3001",
-    "build": "next build",
-    "start": "next start",
-    "lint": "eslint --max-warnings 0",
-    "check-types": "next typegen && tsc --noEmit"
-  },
-  "dependencies": {
-    "@repo/ui": "workspace:*",
-    "next": "16.1.0",
-    "react": "^19.2.0",
-    "react-dom": "^19.2.0"
-  },
-  "devDependencies": {
-    "@repo/eslint-config": "workspace:*",
-    "@repo/typescript-config": "workspace:*",
-    "@types/node": "^22.15.3",
-    "@types/react": "19.2.2",
-    "@types/react-dom": "19.2.2",
-    "eslint": "^9.39.1",
-    "typescript": "5.9.2"
-  }
-}

文件差異過大導致無法顯示
+ 0 - 3
apps/docs/public/file-text.svg


文件差異過大導致無法顯示
+ 0 - 10
apps/docs/public/globe.svg


文件差異過大導致無法顯示
+ 0 - 1
apps/docs/public/next.svg


文件差異過大導致無法顯示
+ 0 - 19
apps/docs/public/turborepo-dark.svg


文件差異過大導致無法顯示
+ 0 - 19
apps/docs/public/turborepo-light.svg


+ 0 - 10
apps/docs/public/vercel.svg

@@ -1,10 +0,0 @@
-<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
-<g clip-path="url(#clip0_977_547)">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5 3L18.5 17H2.5L10.5 3Z" fill="white"/>
-</g>
-<defs>
-<clipPath id="clip0_977_547">
-<rect width="16" height="16" fill="white" transform="translate(2.5 2)"/>
-</clipPath>
-</defs>
-</svg>

文件差異過大導致無法顯示
+ 0 - 3
apps/docs/public/window.svg


+ 0 - 20
apps/docs/tsconfig.json

@@ -1,20 +0,0 @@
-{
-  "extends": "@repo/typescript-config/nextjs.json",
-  "compilerOptions": {
-    "plugins": [
-      {
-        "name": "next"
-      }
-    ]
-  },
-  "include": [
-    "**/*.ts",
-    "**/*.tsx",
-    "next-env.d.ts",
-    "next.config.js",
-    ".next/types/**/*.ts"
-  ],
-  "exclude": [
-    "node_modules"
-  ]
-}

+ 21 - 33
apps/web/.gitignore

@@ -1,36 +1,24 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-.yarn/install-state.gz
-
-# testing
-/coverage
-
-# next.js
-/.next/
-/out/
-
-# production
-/build
-
-# misc
-.DS_Store
-*.pem
-
-# debug
+# Logs
+logs
+*.log
 npm-debug.log*
 yarn-debug.log*
 yarn-error.log*
-
-# env files (can opt-in for commiting if needed)
-.env*
-
-# vercel
-.vercel
-
-# typescript
-*.tsbuildinfo
-next-env.d.ts
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 3 - 0
apps/web/.vscode/extensions.json

@@ -0,0 +1,3 @@
+{
+  "recommendations": ["Vue.volar"]
+}

+ 3 - 34
apps/web/README.md

@@ -1,36 +1,5 @@
-This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/create-next-app).
+# Vue 3 + TypeScript + Vite
 
-## Getting Started
+This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
 
-First, run the development server:
-
-```bash
-npm run dev
-# or
-yarn dev
-# or
-pnpm dev
-# or
-bun dev
-```
-
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
-
-You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
-
-This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load Inter, a custom Google Font.
-
-## Learn More
-
-To learn more about Next.js, take a look at the following resources:
-
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
-
-You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
-
-## Deploy on Vercel
-
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
-
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
+Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).

二進制
apps/web/app/favicon.ico


二進制
apps/web/app/fonts/GeistMonoVF.woff


二進制
apps/web/app/fonts/GeistVF.woff


+ 0 - 50
apps/web/app/globals.css

@@ -1,50 +0,0 @@
-:root {
-  --background: #ffffff;
-  --foreground: #171717;
-}
-
-@media (prefers-color-scheme: dark) {
-  :root {
-    --background: #0a0a0a;
-    --foreground: #ededed;
-  }
-}
-
-html,
-body {
-  max-width: 100vw;
-  overflow-x: hidden;
-}
-
-body {
-  color: var(--foreground);
-  background: var(--background);
-}
-
-* {
-  box-sizing: border-box;
-  padding: 0;
-  margin: 0;
-}
-
-a {
-  color: inherit;
-  text-decoration: none;
-}
-
-.imgDark {
-  display: none;
-}
-
-@media (prefers-color-scheme: dark) {
-  html {
-    color-scheme: dark;
-  }
-
-  .imgLight {
-    display: none;
-  }
-  .imgDark {
-    display: unset;
-  }
-}

+ 0 - 31
apps/web/app/layout.tsx

@@ -1,31 +0,0 @@
-import type { Metadata } from "next";
-import localFont from "next/font/local";
-import "./globals.css";
-
-const geistSans = localFont({
-  src: "./fonts/GeistVF.woff",
-  variable: "--font-geist-sans",
-});
-const geistMono = localFont({
-  src: "./fonts/GeistMonoVF.woff",
-  variable: "--font-geist-mono",
-});
-
-export const metadata: Metadata = {
-  title: "Create Next App",
-  description: "Generated by create next app",
-};
-
-export default function RootLayout({
-  children,
-}: Readonly<{
-  children: React.ReactNode;
-}>) {
-  return (
-    <html lang="en">
-      <body className={`${geistSans.variable} ${geistMono.variable}`}>
-        {children}
-      </body>
-    </html>
-  );
-}

+ 0 - 186
apps/web/app/page.module.css

@@ -1,186 +0,0 @@
-.page {
-  --gray-rgb: 0, 0, 0;
-  --gray-alpha-200: rgba(var(--gray-rgb), 0.08);
-  --gray-alpha-100: rgba(var(--gray-rgb), 0.05);
-
-  --button-primary-hover: #383838;
-  --button-secondary-hover: #f2f2f2;
-
-  display: grid;
-  grid-template-rows: 20px 1fr 20px;
-  align-items: center;
-  justify-items: center;
-  min-height: 100svh;
-  padding: 80px;
-  gap: 64px;
-  font-synthesis: none;
-}
-
-@media (prefers-color-scheme: dark) {
-  .page {
-    --gray-rgb: 255, 255, 255;
-    --gray-alpha-200: rgba(var(--gray-rgb), 0.145);
-    --gray-alpha-100: rgba(var(--gray-rgb), 0.06);
-
-    --button-primary-hover: #ccc;
-    --button-secondary-hover: #1a1a1a;
-  }
-}
-
-.main {
-  display: flex;
-  flex-direction: column;
-  gap: 32px;
-  grid-row-start: 2;
-}
-
-.main ol {
-  font-family: var(--font-geist-mono);
-  padding-left: 0;
-  margin: 0;
-  font-size: 14px;
-  line-height: 24px;
-  letter-spacing: -0.01em;
-  list-style-position: inside;
-}
-
-.main li:not(:last-of-type) {
-  margin-bottom: 8px;
-}
-
-.main code {
-  font-family: inherit;
-  background: var(--gray-alpha-100);
-  padding: 2px 4px;
-  border-radius: 4px;
-  font-weight: 600;
-}
-
-.ctas {
-  display: flex;
-  gap: 16px;
-}
-
-.ctas a {
-  appearance: none;
-  border-radius: 128px;
-  height: 48px;
-  padding: 0 20px;
-  font-family: var(--font-geist-sans);
-  border: 1px solid transparent;
-  transition: background 0.2s, color 0.2s, border-color 0.2s;
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-size: 16px;
-  line-height: 20px;
-  font-weight: 500;
-}
-
-a.primary {
-  background: var(--foreground);
-  color: var(--background);
-  gap: 8px;
-}
-
-a.secondary {
-  border-color: var(--gray-alpha-200);
-  min-width: 180px;
-}
-
-button.secondary {
-  appearance: none;
-  border-radius: 128px;
-  height: 48px;
-  padding: 0 20px;
-  font-family: var(--font-geist-sans);
-  border: 1px solid transparent;
-  transition: background 0.2s, color 0.2s, border-color 0.2s;
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-size: 16px;
-  line-height: 20px;
-  font-weight: 500;
-  background: transparent;
-  border-color: var(--gray-alpha-200);
-  min-width: 180px;
-}
-
-.footer {
-  font-family: var(--font-geist-sans);
-  grid-row-start: 3;
-  display: flex;
-  gap: 24px;
-}
-
-.footer a {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-}
-
-.footer img {
-  flex-shrink: 0;
-}
-
-/* Enable hover only on non-touch devices */
-@media (hover: hover) and (pointer: fine) {
-  a.primary:hover {
-    background: var(--button-primary-hover);
-    border-color: transparent;
-  }
-
-  a.secondary:hover {
-    background: var(--button-secondary-hover);
-    border-color: transparent;
-  }
-
-  .footer a:hover {
-    text-decoration: underline;
-    text-underline-offset: 4px;
-  }
-}
-
-@media (max-width: 600px) {
-  .page {
-    padding: 32px;
-    padding-bottom: 80px;
-  }
-
-  .main {
-    align-items: center;
-  }
-
-  .main ol {
-    text-align: center;
-  }
-
-  .ctas {
-    flex-direction: column;
-  }
-
-  .ctas a {
-    font-size: 14px;
-    height: 40px;
-    padding: 0 16px;
-  }
-
-  a.secondary {
-    min-width: auto;
-  }
-
-  .footer {
-    flex-wrap: wrap;
-    align-items: center;
-    justify-content: center;
-  }
-}
-
-@media (prefers-color-scheme: dark) {
-  .logo {
-    filter: invert();
-  }
-}

文件差異過大導致無法顯示
+ 0 - 102
apps/web/app/page.tsx


+ 0 - 4
apps/web/eslint.config.js

@@ -1,4 +0,0 @@
-import { nextJsConfig } from "@repo/eslint-config/next-js";
-
-/** @type {import("eslint").Linter.Config[]} */
-export default nextJsConfig;

+ 13 - 0
apps/web/index.html

@@ -0,0 +1,13 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>web</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.ts"></script>
+  </body>
+</html>

+ 0 - 4
apps/web/next.config.js

@@ -1,4 +0,0 @@
-/** @type {import('next').NextConfig} */
-const nextConfig = {};
-
-export default nextConfig;

+ 17 - 18
apps/web/package.json

@@ -1,28 +1,27 @@
 {
   "name": "web",
-  "version": "0.1.0",
-  "type": "module",
   "private": true,
+  "version": "0.0.0",
+  "type": "module",
   "scripts": {
-    "dev": "next dev --port 3000",
-    "build": "next build",
-    "start": "next start",
-    "lint": "eslint --max-warnings 0",
-    "check-types": "next typegen && tsc --noEmit"
+    "dev": "vite",
+    "build": "vue-tsc -b && vite build",
+    "preview": "vite preview"
   },
   "dependencies": {
-    "@repo/ui": "workspace:*",
-    "next": "16.1.0",
-    "react": "^19.2.0",
-    "react-dom": "^19.2.0"
+    "vue": "^3.5.24"
   },
   "devDependencies": {
-    "@repo/eslint-config": "workspace:*",
-    "@repo/typescript-config": "workspace:*",
-    "@types/node": "^22.15.3",
-    "@types/react": "19.2.2",
-    "@types/react-dom": "19.2.2",
-    "eslint": "^9.39.1",
-    "typescript": "5.9.2"
+    "@types/node": "^24.10.1",
+    "@vitejs/plugin-vue": "^6.0.1",
+    "@vue/tsconfig": "^0.8.1",
+    "typescript": "~5.9.3",
+    "vite": "npm:rolldown-vite@7.2.5",
+    "vue-tsc": "^3.1.4"
+  },
+  "pnpm": {
+    "overrides": {
+      "vite": "npm:rolldown-vite@7.2.5"
+    }
   }
 }

文件差異過大導致無法顯示
+ 0 - 3
apps/web/public/file-text.svg


文件差異過大導致無法顯示
+ 0 - 10
apps/web/public/globe.svg


文件差異過大導致無法顯示
+ 0 - 1
apps/web/public/next.svg


文件差異過大導致無法顯示
+ 0 - 19
apps/web/public/turborepo-dark.svg


文件差異過大導致無法顯示
+ 0 - 19
apps/web/public/turborepo-light.svg


+ 0 - 10
apps/web/public/vercel.svg

@@ -1,10 +0,0 @@
-<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
-<g clip-path="url(#clip0_977_547)">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5 3L18.5 17H2.5L10.5 3Z" fill="white"/>
-</g>
-<defs>
-<clipPath id="clip0_977_547">
-<rect width="16" height="16" fill="white" transform="translate(2.5 2)"/>
-</clipPath>
-</defs>
-</svg>

文件差異過大導致無法顯示
+ 1 - 0
apps/web/public/vite.svg


文件差異過大導致無法顯示
+ 0 - 3
apps/web/public/window.svg


+ 30 - 0
apps/web/src/App.vue

@@ -0,0 +1,30 @@
+<script setup lang="ts">
+import HelloWorld from './components/HelloWorld.vue'
+</script>
+
+<template>
+  <div>
+    <a href="https://vite.dev" target="_blank">
+      <img src="/vite.svg" class="logo" alt="Vite logo" />
+    </a>
+    <a href="https://vuejs.org/" target="_blank">
+      <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
+    </a>
+  </div>
+  <HelloWorld msg="Vite + Vue" />
+</template>
+
+<style scoped>
+.logo {
+  height: 6em;
+  padding: 1.5em;
+  will-change: filter;
+  transition: filter 300ms;
+}
+.logo:hover {
+  filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.vue:hover {
+  filter: drop-shadow(0 0 2em #42b883aa);
+}
+</style>

+ 1 - 0
apps/web/src/assets/vue.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

+ 41 - 0
apps/web/src/components/HelloWorld.vue

@@ -0,0 +1,41 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+
+defineProps<{ msg: string }>()
+
+const count = ref(0)
+</script>
+
+<template>
+  <h1>{{ msg }}</h1>
+
+  <div class="card">
+    <button type="button" @click="count++">count is {{ count }}</button>
+    <p>
+      Edit
+      <code>components/HelloWorld.vue</code> to test HMR
+    </p>
+  </div>
+
+  <p>
+    Check out
+    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
+      >create-vue</a
+    >, the official Vue + Vite starter
+  </p>
+  <p>
+    Learn more about IDE Support for Vue in the
+    <a
+      href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
+      target="_blank"
+      >Vue Docs Scaling up Guide</a
+    >.
+  </p>
+  <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
+</template>
+
+<style scoped>
+.read-the-docs {
+  color: #888;
+}
+</style>

+ 5 - 0
apps/web/src/main.ts

@@ -0,0 +1,5 @@
+import { createApp } from 'vue'
+import './style.css'
+import App from './App.vue'
+
+createApp(App).mount('#app')

+ 79 - 0
apps/web/src/style.css

@@ -0,0 +1,79 @@
+:root {
+  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
+  line-height: 1.5;
+  font-weight: 400;
+
+  color-scheme: light dark;
+  color: rgba(255, 255, 255, 0.87);
+  background-color: #242424;
+
+  font-synthesis: none;
+  text-rendering: optimizeLegibility;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+a {
+  font-weight: 500;
+  color: #646cff;
+  text-decoration: inherit;
+}
+a:hover {
+  color: #535bf2;
+}
+
+body {
+  margin: 0;
+  display: flex;
+  place-items: center;
+  min-width: 320px;
+  min-height: 100vh;
+}
+
+h1 {
+  font-size: 3.2em;
+  line-height: 1.1;
+}
+
+button {
+  border-radius: 8px;
+  border: 1px solid transparent;
+  padding: 0.6em 1.2em;
+  font-size: 1em;
+  font-weight: 500;
+  font-family: inherit;
+  background-color: #1a1a1a;
+  cursor: pointer;
+  transition: border-color 0.25s;
+}
+button:hover {
+  border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+  outline: 4px auto -webkit-focus-ring-color;
+}
+
+.card {
+  padding: 2em;
+}
+
+#app {
+  max-width: 1280px;
+  margin: 0 auto;
+  padding: 2rem;
+  text-align: center;
+}
+
+@media (prefers-color-scheme: light) {
+  :root {
+    color: #213547;
+    background-color: #ffffff;
+  }
+  a:hover {
+    color: #747bff;
+  }
+  button {
+    background-color: #f9f9f9;
+  }
+}

+ 16 - 0
apps/web/tsconfig.app.json

@@ -0,0 +1,16 @@
+{
+  "extends": "@vue/tsconfig/tsconfig.dom.json",
+  "compilerOptions": {
+    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+    "types": ["vite/client"],
+
+    /* Linting */
+    "strict": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "erasableSyntaxOnly": true,
+    "noFallthroughCasesInSwitch": true,
+    "noUncheckedSideEffectImports": true
+  },
+  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
+}

+ 4 - 17
apps/web/tsconfig.json

@@ -1,20 +1,7 @@
 {
-  "extends": "@repo/typescript-config/nextjs.json",
-  "compilerOptions": {
-    "plugins": [
-      {
-        "name": "next"
-      }
-    ]
-  },
-  "include": [
-    "**/*.ts",
-    "**/*.tsx",
-    "next-env.d.ts",
-    "next.config.js",
-    ".next/types/**/*.ts"
-  ],
-  "exclude": [
-    "node_modules"
+  "files": [],
+  "references": [
+    { "path": "./tsconfig.app.json" },
+    { "path": "./tsconfig.node.json" }
   ]
 }

+ 26 - 0
apps/web/tsconfig.node.json

@@ -0,0 +1,26 @@
+{
+  "compilerOptions": {
+    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+    "target": "ES2023",
+    "lib": ["ES2023"],
+    "module": "ESNext",
+    "types": ["node"],
+    "skipLibCheck": true,
+
+    /* Bundler mode */
+    "moduleResolution": "bundler",
+    "allowImportingTsExtensions": true,
+    "verbatimModuleSyntax": true,
+    "moduleDetection": "force",
+    "noEmit": true,
+
+    /* Linting */
+    "strict": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "erasableSyntaxOnly": true,
+    "noFallthroughCasesInSwitch": true,
+    "noUncheckedSideEffectImports": true
+  },
+  "include": ["vite.config.ts"]
+}

+ 7 - 0
apps/web/vite.config.ts

@@ -0,0 +1,7 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vite.dev/config/
+export default defineConfig({
+  plugins: [vue()],
+})

+ 1 - 0
packages/api-client/README.md

@@ -0,0 +1 @@
+## 接口请求封装

+ 3 - 0
packages/api-client/index.ts

@@ -0,0 +1,3 @@
+import { request } from './request';
+
+export default request;

+ 19 - 0
packages/api-client/package.json

@@ -0,0 +1,19 @@
+{
+  "name": "@repo/api-client",
+  "version": "1.0.0",
+  "private": true,
+  "exports": {
+    ".": "./index.ts"
+  },
+  "scripts": {
+    "genapi": "openapi2ts"
+  },
+  "devDependencies": {
+    "@repo/typescript-config": "workspace:*",
+    "@umijs/openapi": "^1.14.1"
+  },
+  "license": "MIT",
+  "dependencies": {
+    "axios": "^1.13.2"
+  }
+}

+ 332 - 0
packages/api-client/request.ts

@@ -0,0 +1,332 @@
+import type { AxiosRequestConfig, Method, RawAxiosRequestHeaders } from 'axios'
+import axios from 'axios'
+import { IRestApiContext } from './types'
+
+export const NO_NETWORK_ERROR_CODE = 999
+export const STREAM_SEPARATOR = '⧉⇋⇋➽⌑⧉§§\n'
+
+type GenericValue = string | number | boolean | object | null | undefined
+export interface IDataObject {
+  [key: string]: GenericValue | IDataObject | GenericValue[] | IDataObject[]
+}
+
+const BROWSER_ID_STORAGE_KEY = 'n8n-browserId'
+
+const baseURL = 'dev-n8n.shalu.com'
+const getBrowserId = () => {
+  let browserId = localStorage.getItem(BROWSER_ID_STORAGE_KEY)
+  if (!browserId) {
+    browserId = crypto.randomUUID()
+    localStorage.setItem(BROWSER_ID_STORAGE_KEY, browserId)
+  }
+  return browserId
+}
+
+export class ResponseError {
+  name?: string
+  // The HTTP status code of response
+  httpStatusCode?: number
+
+  // The error code in the response
+  errorCode?: number
+
+  // The stack trace of the server
+  serverStackTrace?: string
+
+  // Additional metadata from the server (e.g., EULA URL)
+  meta?: Record<string, unknown>
+
+  /**
+   * Creates an instance of ResponseError.
+   * @param {string} message The error message
+   * @param {number} [errorCode] The error code which can be used by frontend to identify the actual error
+   * @param {number} [httpStatusCode] The HTTP status code the response should have
+   * @param {string} [stack] The stack trace
+   * @param {Record<string, unknown>} [meta] Additional metadata from the server
+   */
+  constructor(
+    message: string,
+    options: {
+      errorCode?: number
+      httpStatusCode?: number
+      stack?: string
+      meta?: Record<string, unknown>
+    } = {}
+  ) {
+    // super(message);
+    this.name = 'ResponseError'
+
+    const { errorCode, httpStatusCode, stack, meta } = options
+    if (errorCode) {
+      this.errorCode = errorCode
+    }
+    if (httpStatusCode) {
+      this.httpStatusCode = httpStatusCode
+    }
+    if (stack) {
+      this.serverStackTrace = stack
+    }
+    if (meta) {
+      this.meta = meta
+    }
+  }
+}
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const legacyParamSerializer = (params: Record<string, any>) =>
+  Object.keys(params)
+    .filter((key) => params[key] !== undefined)
+    .map((key) => {
+      if (Array.isArray(params[key])) {
+        return params[key].map((v: string) => `${key}[]=${encodeURIComponent(v)}`).join('&')
+      }
+      if (typeof params[key] === 'object') {
+        params[key] = JSON.stringify(params[key])
+      }
+      return `${key}=${encodeURIComponent(params[key])}`
+    })
+    .join('&')
+
+export async function request(
+  endpoint: string,
+  config: {
+    method: Method
+    // baseURL: string
+    // endpoint: string
+    headers?: RawAxiosRequestHeaders
+    data?: GenericValue | GenericValue[]
+    withCredentials?: boolean
+  }
+) {
+  const { method, headers, data } = config
+  const options: AxiosRequestConfig = {
+    method,
+    url: endpoint,
+    baseURL,
+    headers: headers ?? {}
+  }
+  if (baseURL.startsWith('/')) {
+    options.headers!['browser-id'] = getBrowserId()
+  }
+  if (
+    import.meta.env.NODE_ENV !== 'production' &&
+    !baseURL.includes('api.n8n.io') &&
+    !baseURL.includes('n8n.cloud')
+  ) {
+    options.withCredentials = options.withCredentials ?? true
+  }
+  if (['POST', 'PATCH', 'PUT'].includes(method)) {
+    options.data = data
+  } else if (data) {
+    options.params = data
+    options.paramsSerializer = legacyParamSerializer
+  }
+
+  try {
+    const response = await axios.request(options)
+    return response.data
+  } catch (error) {
+    if (error.message === 'Network Error') {
+      throw new ResponseError("Can't connect to n8n.", {
+        errorCode: NO_NETWORK_ERROR_CODE
+      })
+    }
+
+    const errorResponseData = error.response?.data
+    if (errorResponseData?.mfaRequired === true) {
+      // throw new MfaRequiredError();
+      throw errorResponseData
+    }
+    if (errorResponseData?.message !== undefined) {
+      if (errorResponseData.name === 'NodeApiError') {
+        errorResponseData.httpStatusCode = error.response.status
+        throw errorResponseData
+      }
+
+      throw new ResponseError(errorResponseData.message, {
+        errorCode: errorResponseData.code,
+        httpStatusCode: error.response.status,
+        stack: errorResponseData.stack,
+        meta: errorResponseData.meta
+      })
+    }
+
+    throw error
+  }
+}
+
+/**
+ * Sends a request to the API and returns the response without extracting the data key.
+ * @param context Rest API context
+ * @param method HTTP method
+ * @param endpoint relative path to the API endpoint
+ * @param data request data
+ * @returns data and total count
+ */
+export async function getFullApiResponse<T>(
+  context: IRestApiContext,
+  method: Method,
+  endpoint: string,
+  data?: GenericValue | GenericValue[]
+) {
+  const response = await request({
+    method,
+    baseURL: context.baseUrl,
+    endpoint,
+    headers: { 'push-ref': context.pushRef },
+    data
+  })
+
+  return response as { count: number; data: T }
+}
+
+export async function makeRestApiRequest<T>(
+  context: IRestApiContext,
+  method: Method,
+  endpoint: string,
+  data?: GenericValue | GenericValue[]
+) {
+  const response = await request({
+    method,
+    baseURL: context.baseUrl,
+    endpoint,
+    headers: { 'push-ref': context.pushRef },
+    data
+  })
+
+  // All cli rest api endpoints return data wrapped in `data` key
+  return response.data as T
+}
+
+export async function get(
+  baseURL: string,
+  endpoint: string,
+  params?: IDataObject,
+  headers?: RawAxiosRequestHeaders
+) {
+  return await request({ method: 'GET', baseURL, endpoint, headers, data: params })
+}
+
+export async function post(
+  baseURL: string,
+  endpoint: string,
+  params?: IDataObject,
+  headers?: RawAxiosRequestHeaders
+) {
+  return await request({ method: 'POST', baseURL, endpoint, headers, data: params })
+}
+
+export async function patch(
+  baseURL: string,
+  endpoint: string,
+  params?: IDataObject,
+  headers?: RawAxiosRequestHeaders
+) {
+  return await request({ method: 'PATCH', baseURL, endpoint, headers, data: params })
+}
+
+export async function streamRequest<T extends object>(
+  context: IRestApiContext,
+  apiEndpoint: string,
+  payload: object,
+  onChunk?: (chunk: T) => void,
+  onDone?: () => void,
+  onError?: (e: Error) => void,
+  separator = STREAM_SEPARATOR,
+  abortSignal?: AbortSignal
+): Promise<void> {
+  let onErrorOnce: ((e: Error) => void) | undefined = (e: Error) => {
+    onErrorOnce = undefined
+    onError?.(e)
+  }
+  const headers: Record<string, string> = {
+    'browser-id': getBrowserId(),
+    'Content-Type': 'application/json'
+  }
+  const assistantRequest: RequestInit = {
+    headers,
+    method: 'POST',
+    credentials: 'include',
+    body: JSON.stringify(payload),
+    signal: abortSignal
+  }
+  try {
+    const response = await fetch(`${context.baseUrl}${apiEndpoint}`, assistantRequest)
+
+    if (response.body) {
+      // Handle the streaming response
+      const reader = response.body.getReader()
+      const decoder = new TextDecoder('utf-8')
+
+      let buffer = ''
+
+      async function readStream() {
+        const { done, value } = await reader.read()
+        if (done) {
+          if (response.ok) {
+            onDone?.()
+          } else {
+            onErrorOnce?.(
+              new ResponseError(response.statusText, {
+                httpStatusCode: response.status
+              })
+            )
+          }
+          return
+        }
+        const chunk = decoder.decode(value)
+        buffer += chunk
+
+        const splitChunks = buffer.split(separator)
+
+        buffer = ''
+        for (const splitChunk of splitChunks) {
+          if (splitChunk) {
+            let data: T
+            try {
+              // data = jsonParse<T>(splitChunk, { errorMessage: 'Invalid json' });
+              data = JSON.parse(splitChunk) as T
+            } catch (e) {
+              // incomplete json. append to buffer to complete
+              buffer += splitChunk
+
+              continue
+            }
+
+            try {
+              if (response.ok) {
+                // Call chunk callback if request was successful
+                onChunk?.(data)
+              } else {
+                // Otherwise, call error callback
+                const message = 'message' in data ? data.message : response.statusText
+                onErrorOnce?.(
+                  new ResponseError(String(message), {
+                    httpStatusCode: response.status
+                  })
+                )
+              }
+            } catch (e: unknown) {
+              if (e instanceof Error) {
+                onErrorOnce?.(e)
+              }
+            }
+          }
+        }
+        await readStream()
+      }
+
+      // Start reading the stream
+      await readStream()
+    } else if (onErrorOnce) {
+      onErrorOnce(new Error(response.statusText))
+    }
+  } catch (e: unknown) {
+    const condition = e instanceof Error
+    if (!condition) {
+      // eslint-disable-next-line n8n-local-rules/no-plain-errors
+      throw new Error('Assertion failed')
+    }
+    onErrorOnce?.(e)
+  }
+}

+ 4 - 0
packages/api-client/types.ts

@@ -0,0 +1,4 @@
+export interface IRestApiContext {
+	baseUrl: string;
+	pushRef: string;
+}

+ 27 - 0
packages/api-service/README.md

@@ -0,0 +1,27 @@
+# 生成 TypeScript 接口与类型
+
+简要说明:使用@umijs/openapi根据 API 文档(OpenAPI/Swagger)生成对应的 TypeScript 接口与类型,使用 `genapi` 脚本调用,配置文件参考 `openapi2ts.config.js`。
+
+## 1. 文件结构(示例)
+- schema.json      — OpenAPI 文档
+- openapi2ts.config.js   — 生成器配置
+- packages/api-service/src/types/api.ts — 生成结果
+- package.json 
+
+## 2. package.json 脚本
+在 packages/api-service/package.json 或仓库根目录的 package.json 中添加:
+```json
+{
+  "scripts": {
+    "genapi": "openapi2ts"
+  }
+}
+```
+
+可使用pnpm运行:
+```
+pnpm run genapi
+```
+
+## 3. 示例配置:openapi2ts.config.js
+配置参考链接:https://github.com/781574155/openapi2typescript#readme

+ 1 - 0
packages/api-service/index.ts

@@ -0,0 +1 @@
+export * from './servers/api'

+ 7 - 0
packages/api-service/openapi2ts.config.ts

@@ -0,0 +1,7 @@
+import path from 'path'
+
+export default {
+  schemaPath: path.resolve(__dirname, './schema.json'),
+  serversPath: './servers',
+  requestLibPath: "import request from '@repo/api-client'",
+}

+ 17 - 0
packages/api-service/package.json

@@ -0,0 +1,17 @@
+{
+  "name": "@repo/api-service",
+  "version": "1.0.0",
+  "private": true,
+  "exports": {
+    ".": "./index.ts"
+  },
+  "scripts": {
+    "genapi": "openapi2ts"
+  },
+  "devDependencies": {
+    "@repo/typescript-config": "workspace:*",
+    "@repo/api-client": "workspace:*",
+    "@umijs/openapi": "^1.14.1"
+  },
+  "license": "MIT"
+}

文件差異過大導致無法顯示
+ 3503 - 0
packages/api-service/schema.json


+ 23 - 0
packages/api-service/servers/api/audit.ts

@@ -0,0 +1,23 @@
+// @ts-ignore
+/* eslint-disable */
+import request from '@repo/api-client'
+
+/** Generate an audit Generate a security audit for your n8n instance. POST /audit */
+export async function postAudit(
+  body: {
+    additionalOptions?: {
+      daysAbandonedWorkflow?: number
+      categories?: ('credentials' | 'database' | 'nodes' | 'filesystem' | 'instance')[]
+    }
+  },
+  options?: { [key: string]: any }
+) {
+  return request<API.audit>('/audit', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}

+ 84 - 0
packages/api-service/servers/api/credential.ts

@@ -0,0 +1,84 @@
+// @ts-ignore
+/* eslint-disable */
+import request from '@repo/api-client'
+
+/** Create a credential Creates a credential that can be used by nodes of the specified type. POST /credentials */
+export async function postCredentials(body: API.credential, options?: { [key: string]: any }) {
+  return request<API.createCredentialResponse>('/credentials', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Delete credential by ID Deletes a credential from your instance. You must be the owner of the credentials DELETE /credentials/${param0} */
+export async function deleteCredential(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.deleteCredentialParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.credential>(`/credentials/${param0}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}
+
+/** Update credential by ID Updates an existing credential. You must be the owner of the credential. PATCH /credentials/${param0} */
+export async function updateCredential(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.updateCredentialParams,
+  body: API.updateCredentialRequest,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.createCredentialResponse>(`/credentials/${param0}`, {
+    method: 'PATCH',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Transfer a credential to another project. Transfer a credential to another project. PUT /credentials/${param0}/transfer */
+export async function putCredentialsIdTransfer(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.putCredentialsIdTransferParams,
+  body: {
+    /** The ID of the project to transfer the credential to. */
+    destinationProjectId: string
+  },
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<any>(`/credentials/${param0}/transfer`, {
+    method: 'PUT',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Show credential data schema GET /credentials/schema/${param0} */
+export async function getCredentialsSchemaCredentialTypeName(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getCredentialsSchemaCredentialTypeNameParams,
+  options?: { [key: string]: any }
+) {
+  const { credentialTypeName: param0, ...queryParams } = params
+  return request<Record<string, any>>(`/credentials/schema/${param0}`, {
+    method: 'GET',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}

+ 72 - 0
packages/api-service/servers/api/execution.ts

@@ -0,0 +1,72 @@
+// @ts-ignore
+/* eslint-disable */
+import request from '@repo/api-client'
+
+/** Retrieve all executions Retrieve all executions from your instance. GET /executions */
+export async function getExecutions(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getExecutionsParams,
+  options?: { [key: string]: any }
+) {
+  return request<API.executionList>('/executions', {
+    method: 'GET',
+    params: {
+      // limit has a default value: 100
+      limit: '100',
+      ...params
+    },
+    ...(options || {})
+  })
+}
+
+/** Retrieve an execution Retrieve an execution from your instance. GET /executions/${param0} */
+export async function getExecutionsId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getExecutionsIdParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.execution>(`/executions/${param0}`, {
+    method: 'GET',
+    params: {
+      ...queryParams
+    },
+    ...(options || {})
+  })
+}
+
+/** Delete an execution Deletes an execution from your instance. DELETE /executions/${param0} */
+export async function deleteExecutionsId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.deleteExecutionsIdParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.execution>(`/executions/${param0}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}
+
+/** Retry an execution Retry an execution from your instance. POST /executions/${param0}/retry */
+export async function postExecutionsIdRetry(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.postExecutionsIdRetryParams,
+  body: {
+    /** Whether to load the currently saved workflow to execute instead of the one saved at the time of the execution. If set to true, it will retry with the latest version of the workflow. */
+    loadWorkflow?: boolean
+  },
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.execution>(`/executions/${param0}/retry`, {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}

+ 24 - 0
packages/api-service/servers/api/index.ts

@@ -0,0 +1,24 @@
+// @ts-ignore
+/* eslint-disable */
+// API 更新时间:
+// API 唯一标识:
+import * as audit from './audit'
+import * as credential from './credential'
+import * as execution from './execution'
+import * as tags from './tags'
+import * as workflow from './workflow'
+import * as user from './user'
+import * as sourceControl from './sourceControl'
+import * as variables from './variables'
+import * as projects from './projects'
+export default {
+  audit,
+  credential,
+  execution,
+  tags,
+  workflow,
+  user,
+  sourceControl,
+  variables,
+  projects
+}

+ 123 - 0
packages/api-service/servers/api/projects.ts

@@ -0,0 +1,123 @@
+// @ts-ignore
+/* eslint-disable */
+import request from '@repo/api-client'
+
+/** Retrieve projects Retrieve projects from your instance. GET /projects */
+export async function getProjects(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getProjectsParams,
+  options?: { [key: string]: any }
+) {
+  return request<API.projectList>('/projects', {
+    method: 'GET',
+    params: {
+      // limit has a default value: 100
+      limit: '100',
+      ...params
+    },
+    ...(options || {})
+  })
+}
+
+/** Create a project Create a project on your instance. POST /projects */
+export async function postProjects(body: API.project, options?: { [key: string]: any }) {
+  return request<any>('/projects', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Update a project Update a project on your instance. PUT /projects/${param0} */
+export async function putProjectsProjectId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.putProjectsProjectIdParams,
+  body: API.project,
+  options?: { [key: string]: any }
+) {
+  const { projectId: param0, ...queryParams } = params
+  return request<any>(`/projects/${param0}`, {
+    method: 'PUT',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Delete a project Delete a project from your instance. DELETE /projects/${param0} */
+export async function deleteProjectsProjectId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.deleteProjectsProjectIdParams,
+  options?: { [key: string]: any }
+) {
+  const { projectId: param0, ...queryParams } = params
+  return request<any>(`/projects/${param0}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}
+
+/** Add one or more users to a project Add one or more users to a project on your instance. POST /projects/${param0}/users */
+export async function postProjectsProjectIdUsers(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.postProjectsProjectIdUsersParams,
+  body: {
+    /** A list of userIds and roles to add to the project. */
+    relations: { userId: string; role: string }[]
+  },
+  options?: { [key: string]: any }
+) {
+  const { projectId: param0, ...queryParams } = params
+  return request<any>(`/projects/${param0}/users`, {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Delete a user from a project Delete a user from a project on your instance. DELETE /projects/${param0}/users/${param1} */
+export async function deleteProjectsProjectIdUsersUserId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.deleteProjectsProjectIdUsersUserIdParams,
+  options?: { [key: string]: any }
+) {
+  const { projectId: param0, userId: param1, ...queryParams } = params
+  return request<any>(`/projects/${param0}/users/${param1}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}
+
+/** Change a user's role in a project Change a user's role in a project. PATCH /projects/${param0}/users/${param1} */
+export async function patchProjectsProjectIdUsersUserId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.patchProjectsProjectIdUsersUserIdParams,
+  body: {
+    /** The role assigned to the user in the project. */
+    role: string
+  },
+  options?: { [key: string]: any }
+) {
+  const { projectId: param0, userId: param1, ...queryParams } = params
+  return request<any>(`/projects/${param0}/users/${param1}`, {
+    method: 'PATCH',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}

+ 15 - 0
packages/api-service/servers/api/sourceControl.ts

@@ -0,0 +1,15 @@
+// @ts-ignore
+/* eslint-disable */
+import request from '@repo/api-client'
+
+/** Pull changes from the remote repository Requires the Source Control feature to be licensed and connected to a repository. POST /source-control/pull */
+export async function postSourceControlPull(body: API.pull, options?: { [key: string]: any }) {
+  return request<API.importResult>('/source-control/pull', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}

+ 79 - 0
packages/api-service/servers/api/tags.ts

@@ -0,0 +1,79 @@
+// @ts-ignore
+/* eslint-disable */
+import request from '@repo/api-client'
+
+/** Retrieve all tags Retrieve all tags from your instance. GET /tags */
+export async function getTags(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getTagsParams,
+  options?: { [key: string]: any }
+) {
+  return request<API.tagList>('/tags', {
+    method: 'GET',
+    params: {
+      // limit has a default value: 100
+      limit: '100',
+      ...params
+    },
+    ...(options || {})
+  })
+}
+
+/** Create a tag Create a tag in your instance. POST /tags */
+export async function postTags(body: API.tag, options?: { [key: string]: any }) {
+  return request<API.tag>('/tags', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Retrieves a tag Retrieves a tag. GET /tags/${param0} */
+export async function getTagsId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getTagsIdParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.tag>(`/tags/${param0}`, {
+    method: 'GET',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}
+
+/** Update a tag Update a tag. PUT /tags/${param0} */
+export async function putTagsId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.putTagsIdParams,
+  body: API.tag,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.tag>(`/tags/${param0}`, {
+    method: 'PUT',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Delete a tag Deletes a tag. DELETE /tags/${param0} */
+export async function deleteTagsId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.deleteTagsIdParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.tag>(`/tags/${param0}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}

+ 643 - 0
packages/api-service/servers/api/typings.d.ts

@@ -0,0 +1,643 @@
+declare namespace API {
+  
+        type activeVersion =
+          {
+              /** Unique identifier for this workflow version */
+                'versionId'?: string;
+              /** The workflow this version belongs to */
+                'workflowId'?: string;
+                'nodes'?: node[];
+                'connections'?: Record<string, any>;
+              /** Comma-separated list of author IDs who contributed to this version */
+                'authors'?: string;
+                'createdAt'?: string;
+                'updatedAt'?: string;
+          }
+        
+  
+        type audit =
+          {
+                'Credentials Risk Report'?: Record<string, any>;
+                'Database Risk Report'?: Record<string, any>;
+                'Filesystem Risk Report'?: Record<string, any>;
+                'Nodes Risk Report'?: Record<string, any>;
+                'Instance Risk Report'?: Record<string, any>;
+          }
+        
+  
+        type Audit = [object Object];
+  
+        type create =
+          {
+                'id'?: string;
+                'key': string;
+                'value': string;
+                'type'?: string;
+                'projectId'?: string;
+          }
+        
+  
+        type createCredentialResponse =
+          {
+                'id': string;
+                'name': string;
+                'type': string;
+                'createdAt': string;
+                'updatedAt': string;
+          }
+        
+  
+        type credential =
+          {
+                'id'?: string;
+                'name': string;
+                'type': string;
+                'data': Record<string, any>;
+              /** Whether this credential has resolvable fields */
+                'isResolvable'?: boolean;
+                'createdAt'?: string;
+                'updatedAt'?: string;
+          }
+        
+  
+        type Credential = [object Object];
+  
+        type credentialType =
+          {
+                'displayName'?: string;
+                'name'?: string;
+                'type'?: string;
+                'default'?: string;
+          }
+        
+  
+        type CredentialType = [object Object];
+  
+        type deleteCredentialParams =
+          {
+              /** The credential ID that needs to be deleted */
+                'id': string;
+          }
+        
+  
+        type deleteExecutionsIdParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type deleteProjectsProjectIdParams =
+          {
+              /** The ID of the project. */
+                'projectId': string;
+          }
+        
+  
+        type deleteProjectsProjectIdUsersUserIdParams =
+          {
+              /** The ID of the project. */
+                'projectId': string;
+              /** The ID of the user. */
+                'userId': string;
+          }
+        
+  
+        type deleteTagsIdParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type deleteUsersIdParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type deleteVariablesIdParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type deleteWorkflowsIdParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type error =
+          {
+                'code'?: string;
+                'message': string;
+                'description'?: string;
+          }
+        
+  
+        type Error = [object Object];
+  
+        type execution =
+          {
+                'id'?: number;
+                'data'?: Record<string, any>;
+                'finished'?: boolean;
+                'mode'?: "cli" | "error" | "integrated" | "internal" | "manual" | "retry" | "trigger" | "webhook" | "evaluation" | "chat";
+                'retryOf'?: number;
+                'retrySuccessId'?: number;
+                'startedAt'?: string;
+              /** The time at which the execution stopped. Will only be null for executions that still have the status 'running'. */
+                'stoppedAt'?: string;
+                'workflowId'?: number;
+                'waitTill'?: string;
+                'customData'?: Record<string, any>;
+                'status'?: "canceled" | "crashed" | "error" | "new" | "running" | "success" | "unknown" | "waiting";
+          }
+        
+  
+        type Execution = [object Object];
+  
+        type executionList =
+          {
+                'data'?: execution[];
+              /** Paginate through executions by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
+                'nextCursor'?: string;
+          }
+        
+  
+        type ExecutionList = [object Object];
+  
+        type getCredentialsSchemaCredentialTypeNameParams =
+          {
+              /** The credential type name that you want to get the schema for */
+                'credentialTypeName': string;
+          }
+        
+  
+        type getExecutionsIdParams =
+          {
+                ''?: any;
+                ''?: any;
+          }
+        
+  
+        type getExecutionsParams =
+          {
+                ''?: any;
+              /** Status to filter the executions by. */
+                'status'?: "canceled" | "error" | "running" | "success" | "waiting";
+              /** Workflow to filter the executions by. */
+                'workflowId'?: string;
+                'projectId'?: string;
+                ''?: any;
+                ''?: any;
+          }
+        
+  
+        type getProjectsParams =
+          {
+                ''?: any;
+                ''?: any;
+          }
+        
+  
+        type getTagsIdParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type getTagsParams =
+          {
+                ''?: any;
+                ''?: any;
+          }
+        
+  
+        type getUsersIdParams =
+          {
+                ''?: any;
+                ''?: any;
+          }
+        
+  
+        type getUsersParams =
+          {
+                ''?: any;
+                ''?: any;
+                ''?: any;
+                'projectId'?: string;
+          }
+        
+  
+        type getVariablesParams =
+          {
+                ''?: any;
+                ''?: any;
+                'projectId'?: string;
+                'state'?: "empty";
+          }
+        
+  
+        type getWorkflowsIdParams =
+          {
+              /** Set this to avoid retrieving pinned data */
+                'excludePinnedData'?: boolean;
+                ''?: any;
+          }
+        
+  
+        type getWorkflowsIdTagsParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type getWorkflowsIdVersionIdParams =
+          {
+                ''?: any;
+              /** The version ID to retrieve */
+                'versionId': string;
+          }
+        
+  
+        type getWorkflowsParams =
+          {
+                'active'?: boolean;
+                'tags'?: string;
+                'name'?: string;
+                'projectId'?: string;
+              /** Set this to avoid retrieving pinned data */
+                'excludePinnedData'?: boolean;
+                ''?: any;
+                ''?: any;
+          }
+        
+  
+        type importResult =
+          {
+                'variables'?: { 'added'?: string[]; 'changed'?: string[]; };
+                'credentials'?: { 'id'?: string; 'name'?: string; 'type'?: string; }[];
+                'workflows'?: { 'id'?: string; 'name'?: string; }[];
+                'tags'?: { 'tags'?: { 'id'?: string; 'name'?: string; }[]; 'mappings'?: { 'workflowId'?: string; 'tagId'?: string; }[]; };
+          }
+        
+  
+        type ImportResult = [object Object];
+  
+        type node =
+          {
+                'id'?: string;
+                'name'?: string;
+                'webhookId'?: string;
+                'disabled'?: boolean;
+                'notesInFlow'?: boolean;
+                'notes'?: string;
+                'type'?: string;
+                'typeVersion'?: number;
+                'executeOnce'?: boolean;
+                'alwaysOutputData'?: boolean;
+                'retryOnFail'?: boolean;
+                'maxTries'?: number;
+                'waitBetweenTries'?: number;
+              /** use onError instead */
+                'continueOnFail'?: boolean;
+                'onError'?: string;
+                'position'?: number[];
+                'parameters'?: Record<string, any>;
+                'credentials'?: Record<string, any>;
+                'createdAt'?: string;
+                'updatedAt'?: string;
+          }
+        
+  
+        type Node = [object Object];
+  
+        type patchProjectsProjectIdUsersUserIdParams =
+          {
+              /** The ID of the project. */
+                'projectId': string;
+              /** The ID of the user. */
+                'userId': string;
+          }
+        
+  
+        type patchUsersIdRoleParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type postExecutionsIdRetryParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type postProjectsProjectIdUsersParams =
+          {
+              /** The ID of the project. */
+                'projectId': string;
+          }
+        
+  
+        type postWorkflowsIdActivateParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type postWorkflowsIdDeactivateParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type project =
+          {
+                'id'?: string;
+                'name': string;
+                'type'?: string;
+          }
+        
+  
+        type projectList =
+          {
+                'data'?: project[];
+              /** Paginate through projects by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
+                'nextCursor'?: string;
+          }
+        
+  
+        type pull =
+          {
+                'force'?: boolean;
+                'variables'?: Record<string, any>;
+          }
+        
+  
+        type Pull = [object Object];
+  
+        type putCredentialsIdTransferParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type putProjectsProjectIdParams =
+          {
+              /** The ID of the project. */
+                'projectId': string;
+          }
+        
+  
+        type putTagsIdParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type putVariablesIdParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type putWorkflowsIdParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type putWorkflowsIdTagsParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type putWorkflowsIdTransferParams =
+          {
+                ''?: any;
+          }
+        
+  
+        type role =
+          {
+                'id'?: number;
+                'name'?: string;
+                'scope'?: string;
+              /** Time the role was created. */
+                'createdAt'?: string;
+              /** Last time the role was updated. */
+                'updatedAt'?: string;
+          }
+        
+  
+        type Role = [object Object];
+  
+        type sharedWorkflow =
+          {
+                'role'?: string;
+                'workflowId'?: string;
+                'projectId'?: string;
+                'project'?: { 'id'?: string; 'name'?: string; 'type'?: string; };
+                'createdAt'?: string;
+                'updatedAt'?: string;
+          }
+        
+  
+        type tag =
+          {
+                'id'?: string;
+                'name': string;
+                'createdAt'?: string;
+                'updatedAt'?: string;
+          }
+        
+  
+        type Tag = [object Object];
+  
+        type tagIds = Record<string, any>;
+  
+        type tagList =
+          {
+                'data'?: tag[];
+              /** Paginate through tags by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
+                'nextCursor'?: string;
+          }
+        
+  
+        type updateCredentialParams =
+          {
+              /** The credential ID that needs to be updated */
+                'id': string;
+          }
+        
+  
+        type updateCredentialRequest =
+          {
+              /** The name of the credential */
+                'name'?: string;
+              /** The credential type. If changing type, data must also be provided. */
+                'type'?: string;
+              /** The credential data. Required when changing credential type. */
+                'data'?: Record<string, any>;
+              /** Whether this credential is available globally */
+                'isGlobal'?: boolean;
+              /** Whether this credential has resolvable fields */
+                'isResolvable'?: boolean;
+              /** If true, unredacts and merges existing credential data with the provided data. If false, replaces the entire data object. */
+                'isPartialData'?: boolean;
+          }
+        
+  
+        type user =
+          {
+                'id'?: string;
+                'email': string;
+              /** User's first name */
+                'firstName'?: string;
+              /** User's last name */
+                'lastName'?: string;
+              /** Whether the user finished setting up their account in response to the invitation (true) or not (false). */
+                'isPending'?: boolean;
+              /** Time the user was created. */
+                'createdAt'?: string;
+              /** Last time the user was updated. */
+                'updatedAt'?: string;
+                'role'?: string;
+          }
+        
+  
+        type User = [object Object];
+  
+        type userList =
+          {
+                'data'?: user[];
+              /** Paginate through users by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
+                'nextCursor'?: string;
+          }
+        
+  
+        type UserList = [object Object];
+  
+        type variable =
+          {
+                'id'?: string;
+                'key': string;
+                'value': string;
+                'type'?: string;
+                'project'?: project;
+          }
+        
+  
+        type variableList =
+          {
+                'data'?: variable[];
+              /** Paginate through variables by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
+                'nextCursor'?: string;
+          }
+        
+  
+        type workflow =
+          {
+                'id'?: string;
+                'name': string;
+                'active'?: boolean;
+                'createdAt'?: string;
+                'updatedAt'?: string;
+                'nodes': node[];
+                'connections': Record<string, any>;
+                'settings': workflowSettings;
+                'staticData'?: string | Record<string, any>;
+                'tags'?: tag[];
+                'shared'?: sharedWorkflow[];
+                'activeVersion'?: activeVersion;
+          }
+        
+  
+        type Workflow = [object Object];
+  
+        type workflowList =
+          {
+                'data'?: workflow[];
+              /** Paginate through workflows by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
+                'nextCursor'?: string;
+          }
+        
+  
+        type WorkflowList = [object Object];
+  
+        type workflowSettings =
+          {
+                'saveExecutionProgress'?: boolean;
+                'saveManualExecutions'?: boolean;
+                'saveDataErrorExecution'?: "all" | "none";
+                'saveDataSuccessExecution'?: "all" | "none";
+                'executionTimeout'?: number;
+              /** The ID of the workflow that contains the error trigger node. */
+                'errorWorkflow'?: string;
+                'timezone'?: string;
+                'executionOrder'?: string;
+              /** Controls which workflows are allowed to call this workflow using the Execute Workflow node.
+
+Available options:
+- `any`: Any workflow can call this workflow (no restrictions)
+- `none`: No other workflows can call this workflow (completely blocked)
+- `workflowsFromSameOwner` (default): Only workflows owned by the same project can call this workflow
+  * For personal projects: Only workflows created by the same user
+  * For team projects: Only workflows within the same team project
+- `workflowsFromAList`: Only specific workflows listed in the `callerIds` field can call this workflow
+  * Requires the `callerIds` field to specify which workflow IDs are allowed
+  * See `callerIds` field documentation for usage
+ */
+                'callerPolicy'?: "any" | "none" | "workflowsFromAList" | "workflowsFromSameOwner";
+              /** Comma-separated list of workflow IDs allowed to call this workflow (only used with workflowsFromAList policy) */
+                'callerIds'?: string;
+              /** Estimated time saved per execution in minutes */
+                'timeSavedPerExecution'?: number;
+              /** Controls whether this workflow is accessible via the Model Context Protocol (MCP).
+
+When enabled, this workflow can be called by MCP clients (AI assistants and other tools
+that support MCP). This allows external AI tools to discover and execute this workflow
+as part of their capabilities.
+
+Requirements for enabling MCP access:
+- The workflow must be active (not deactivated)
+- The workflow must contain at least one active Webhook node
+- Only webhook-triggered workflows can be exposed via MCP
+
+Security note: When a workflow is available in MCP, it can be discovered and executed
+by any MCP client that has the appropriate API credentials for your n8n instance.
+ */
+                'availableInMCP'?: boolean;
+          }
+        
+  
+        type WorkflowSettings = [object Object];
+  
+        type workflowTags = tag[];
+  
+        type workflowVersion =
+          {
+              /** The version ID of this workflow snapshot */
+                'versionId': string;
+              /** The workflow ID this version belongs to */
+                'workflowId': string;
+              /** Nodes as they were in this version */
+                'nodes': node[];
+              /** Connections as they were in this version */
+                'connections': Record<string, any>;
+              /** Authors who created this version */
+                'authors': string;
+              /** Workflow name at this version */
+                'name'?: string;
+              /** Workflow description at this version */
+                'description'?: string;
+              /** When this version was created */
+                'createdAt'?: string;
+              /** When this version was last updated */
+                'updatedAt'?: string;
+          }
+        
+  
+}

+ 90 - 0
packages/api-service/servers/api/user.ts

@@ -0,0 +1,90 @@
+// @ts-ignore
+/* eslint-disable */
+import request from '@repo/api-client'
+
+/** Retrieve all users Retrieve all users from your instance. Only available for the instance owner. GET /users */
+export async function getUsers(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getUsersParams,
+  options?: { [key: string]: any }
+) {
+  return request<API.userList>('/users', {
+    method: 'GET',
+    params: {
+      // limit has a default value: 100
+      limit: '100',
+
+      ...params
+    },
+    ...(options || {})
+  })
+}
+
+/** Create multiple users Create one or more users. POST /users */
+export async function postUsers(
+  body: { email: string; role?: string }[],
+  options?: { [key: string]: any }
+) {
+  return request<{
+    user?: { id?: string; email?: string; inviteAcceptUrl?: string; emailSent?: boolean }
+    error?: string
+  }>('/users', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Get user by ID/Email Retrieve a user from your instance. Only available for the instance owner. GET /users/${param0} */
+export async function getUsersId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getUsersIdParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.user>(`/users/${param0}`, {
+    method: 'GET',
+    params: {
+      ...queryParams
+    },
+    ...(options || {})
+  })
+}
+
+/** Delete a user Delete a user from your instance. DELETE /users/${param0} */
+export async function deleteUsersId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.deleteUsersIdParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<any>(`/users/${param0}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}
+
+/** Change a user's global role Change a user's global role PATCH /users/${param0}/role */
+export async function patchUsersIdRole(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.patchUsersIdRoleParams,
+  body: {
+    newRoleName: string
+  },
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<any>(`/users/${param0}/role`, {
+    method: 'PATCH',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}

+ 66 - 0
packages/api-service/servers/api/variables.ts

@@ -0,0 +1,66 @@
+// @ts-ignore
+/* eslint-disable */
+import request from '@repo/api-client'
+
+/** Retrieve variables Retrieve variables from your instance. GET /variables */
+export async function getVariables(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getVariablesParams,
+  options?: { [key: string]: any }
+) {
+  return request<API.variableList>('/variables', {
+    method: 'GET',
+    params: {
+      // limit has a default value: 100
+      limit: '100',
+
+      ...params
+    },
+    ...(options || {})
+  })
+}
+
+/** Create a variable Create a variable in your instance. POST /variables */
+export async function postVariables(body: API.create, options?: { [key: string]: any }) {
+  return request<any>('/variables', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Update a variable Update a variable from your instance. PUT /variables/${param0} */
+export async function putVariablesId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.putVariablesIdParams,
+  body: API.create,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<any>(`/variables/${param0}`, {
+    method: 'PUT',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Delete a variable Delete a variable from your instance. DELETE /variables/${param0} */
+export async function deleteVariablesId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.deleteVariablesIdParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<any>(`/variables/${param0}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}

+ 190 - 0
packages/api-service/servers/api/workflow.ts

@@ -0,0 +1,190 @@
+// @ts-ignore
+/* eslint-disable */
+import request from '@repo/api-client'
+
+/** Retrieve all workflows Retrieve all workflows from your instance. GET /workflows */
+export async function getWorkflows(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getWorkflowsParams,
+  options?: { [key: string]: any }
+) {
+  return request<API.workflowList>('/workflows', {
+    method: 'GET',
+    params: {
+      // limit has a default value: 100
+      limit: '100',
+      ...params
+    },
+    ...(options || {})
+  })
+}
+
+/** Create a workflow Create a workflow in your instance. POST /workflows */
+export async function postWorkflows(body: API.workflow, options?: { [key: string]: any }) {
+  return request<API.workflow>('/workflows', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Retrieve a workflow Retrieve a workflow. GET /workflows/${param0} */
+export async function getWorkflowsId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getWorkflowsIdParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.workflow>(`/workflows/${param0}`, {
+    method: 'GET',
+    params: {
+      ...queryParams
+    },
+    ...(options || {})
+  })
+}
+
+/** Update a workflow Update a workflow. If the workflow is published, the updated version will be automatically re-published. PUT /workflows/${param0} */
+export async function putWorkflowsId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.putWorkflowsIdParams,
+  body: API.workflow,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.workflow>(`/workflows/${param0}`, {
+    method: 'PUT',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Delete a workflow Delete a workflow. DELETE /workflows/${param0} */
+export async function deleteWorkflowsId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.deleteWorkflowsIdParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.workflow>(`/workflows/${param0}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}
+
+/** Retrieves a specific version of a workflow Retrieves a specific version of a workflow from workflow history. GET /workflows/${param0}/${param1} */
+export async function getWorkflowsIdVersionId(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getWorkflowsIdVersionIdParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, versionId: param1, ...queryParams } = params
+  return request<API.workflowVersion>(`/workflows/${param0}/${param1}`, {
+    method: 'GET',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}
+
+/** Publish a workflow Publish a workflow. In n8n v1, this action was termed activating a workflow. POST /workflows/${param0}/activate */
+export async function postWorkflowsIdActivate(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.postWorkflowsIdActivateParams,
+  body: {
+    /** The specific version ID to activate or publish. If not provided, the latest version is used. */
+    versionId?: string
+    /** Optional name for the workflow version during activation. */
+    name?: string
+    /** Optional description for the workflow version during activation. */
+    description?: string
+  },
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.workflow>(`/workflows/${param0}/activate`, {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Deactivate a workflow Deactivate a workflow. POST /workflows/${param0}/deactivate */
+export async function postWorkflowsIdDeactivate(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.postWorkflowsIdDeactivateParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.workflow>(`/workflows/${param0}/deactivate`, {
+    method: 'POST',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}
+
+/** Get workflow tags Get workflow tags. GET /workflows/${param0}/tags */
+export async function getWorkflowsIdTags(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.getWorkflowsIdTagsParams,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.workflowTags>(`/workflows/${param0}/tags`, {
+    method: 'GET',
+    params: { ...queryParams },
+    ...(options || {})
+  })
+}
+
+/** Update tags of a workflow Update tags of a workflow. PUT /workflows/${param0}/tags */
+export async function putWorkflowsIdTags(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.putWorkflowsIdTagsParams,
+  body: API.tagIds,
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<API.workflowTags>(`/workflows/${param0}/tags`, {
+    method: 'PUT',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}
+
+/** Transfer a workflow to another project Transfer a workflow to another project PUT /workflows/${param0}/transfer */
+export async function putWorkflowsIdTransfer(
+  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+  params: API.putWorkflowsIdTransferParams,
+  body: {
+    /** The ID of the project to transfer the workflow to. */
+    destinationProjectId: string
+  },
+  options?: { [key: string]: any }
+) {
+  const { id: param0, ...queryParams } = params
+  return request<any>(`/workflows/${param0}/transfer`, {
+    method: 'PUT',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {})
+  })
+}

+ 6 - 0
packages/api-service/tsconfig.json

@@ -0,0 +1,6 @@
+{
+  "extends": "@repo/typescript-config/base.json",
+  "exclude": [
+    "node_modules"
+  ]
+}

+ 0 - 57
packages/eslint-config/next.js

@@ -1,57 +0,0 @@
-import js from "@eslint/js";
-import { globalIgnores } from "eslint/config";
-import eslintConfigPrettier from "eslint-config-prettier";
-import tseslint from "typescript-eslint";
-import pluginReactHooks from "eslint-plugin-react-hooks";
-import pluginReact from "eslint-plugin-react";
-import globals from "globals";
-import pluginNext from "@next/eslint-plugin-next";
-import { config as baseConfig } from "./base.js";
-
-/**
- * A custom ESLint configuration for libraries that use Next.js.
- *
- * @type {import("eslint").Linter.Config[]}
- * */
-export const nextJsConfig = [
-  ...baseConfig,
-  js.configs.recommended,
-  eslintConfigPrettier,
-  ...tseslint.configs.recommended,
-  globalIgnores([
-    // Default ignores of eslint-config-next:
-    ".next/**",
-    "out/**",
-    "build/**",
-    "next-env.d.ts",
-  ]),
-  {
-    ...pluginReact.configs.flat.recommended,
-    languageOptions: {
-      ...pluginReact.configs.flat.recommended.languageOptions,
-      globals: {
-        ...globals.serviceworker,
-      },
-    },
-  },
-  {
-    plugins: {
-      "@next/next": pluginNext,
-    },
-    rules: {
-      ...pluginNext.configs.recommended.rules,
-      ...pluginNext.configs["core-web-vitals"].rules,
-    },
-  },
-  {
-    plugins: {
-      "react-hooks": pluginReactHooks,
-    },
-    settings: { react: { version: "detect" } },
-    rules: {
-      ...pluginReactHooks.configs.recommended.rules,
-      // React scope no longer necessary with new JSX transform.
-      "react/react-in-jsx-scope": "off",
-    },
-  },
-];

+ 36 - 0
packages/eslint-config/vue.js

@@ -0,0 +1,36 @@
+import { defineConfig } from 'eslint/config'
+import eslintPluginVue from 'eslint-plugin-vue'
+import vueParser from 'vue-eslint-parser'
+
+export default defineConfig(
+  { ignores: ['**/node_modules', '**/dist', '**/out'] },
+  eslintPluginVue.configs['flat/recommended'],
+  {
+    files: ['**/*.vue'],
+    languageOptions: {
+      parser: vueParser,
+      parserOptions: {
+        ecmaFeatures: {
+          jsx: true
+        },
+        extraFileExtensions: ['.vue'],
+      }
+    }
+  },
+  {
+    files: ['**/*.{ts,mts,tsx,vue}'],
+    rules: {
+      'vue/require-default-prop': 'off',
+      'vue/multi-word-component-names': 'off',
+      'vue/block-lang': [
+        'error',
+        {
+          script: {
+            lang: 'ts'
+          }
+        }
+      ]
+    }
+  },
+  eslintConfigPrettier
+)

+ 2 - 1
packages/typescript-config/base.json

@@ -14,6 +14,7 @@
     "resolveJsonModule": true,
     "skipLibCheck": true,
     "strict": true,
-    "target": "ES2022"
+    "target": "ES2022",
+    "experimentalDecorators": true,
   }
 }

+ 0 - 12
packages/typescript-config/nextjs.json

@@ -1,12 +0,0 @@
-{
-  "$schema": "https://json.schemastore.org/tsconfig",
-  "extends": "./base.json",
-  "compilerOptions": {
-    "plugins": [{ "name": "next" }],
-    "module": "ESNext",
-    "moduleResolution": "Bundler",
-    "allowJs": true,
-    "jsx": "preserve",
-    "noEmit": true
-  }
-}

+ 3 - 0
packages/typescript-config/package.json

@@ -5,5 +5,8 @@
   "license": "MIT",
   "publishConfig": {
     "access": "public"
+  },
+  "devDependencies": {
+    "@repo/typescript-config": "workspace:*"
   }
 }

+ 8 - 0
packages/typescript-config/vue.json

@@ -0,0 +1,8 @@
+{
+  "$schema": "https://json.schemastore.org/tsconfig",
+  "extends": "./base.json",
+  "compilerOptions": {
+    "jsxImportSource": "vue",
+    "jsx": "preserve"
+  }
+}

+ 0 - 4
packages/ui/eslint.config.mjs

@@ -1,4 +0,0 @@
-import { config } from "@repo/eslint-config/react-internal";
-
-/** @type {import("eslint").Linter.Config} */
-export default config;

+ 0 - 26
packages/ui/package.json

@@ -1,26 +0,0 @@
-{
-  "name": "@repo/ui",
-  "version": "0.0.0",
-  "private": true,
-  "exports": {
-    "./*": "./src/*.tsx"
-  },
-  "scripts": {
-    "lint": "eslint . --max-warnings 0",
-    "generate:component": "turbo gen react-component",
-    "check-types": "tsc --noEmit"
-  },
-  "devDependencies": {
-    "@repo/eslint-config": "workspace:*",
-    "@repo/typescript-config": "workspace:*",
-    "@types/node": "^22.15.3",
-    "@types/react": "19.2.2",
-    "@types/react-dom": "19.2.2",
-    "eslint": "^9.39.1",
-    "typescript": "5.9.2"
-  },
-  "dependencies": {
-    "react": "^19.2.0",
-    "react-dom": "^19.2.0"
-  }
-}

+ 0 - 20
packages/ui/src/button.tsx

@@ -1,20 +0,0 @@
-"use client";
-
-import { ReactNode } from "react";
-
-interface ButtonProps {
-  children: ReactNode;
-  className?: string;
-  appName: string;
-}
-
-export const Button = ({ children, className, appName }: ButtonProps) => {
-  return (
-    <button
-      className={className}
-      onClick={() => alert(`Hello from your ${appName} app!`)}
-    >
-      {children}
-    </button>
-  );
-};

+ 0 - 27
packages/ui/src/card.tsx

@@ -1,27 +0,0 @@
-import { type JSX } from "react";
-
-export function Card({
-  className,
-  title,
-  children,
-  href,
-}: {
-  className?: string;
-  title: string;
-  children: React.ReactNode;
-  href: string;
-}): JSX.Element {
-  return (
-    <a
-      className={className}
-      href={`${href}?utm_source=create-turbo&utm_medium=basic&utm_campaign=create-turbo"`}
-      rel="noopener noreferrer"
-      target="_blank"
-    >
-      <h2>
-        {title} <span>-&gt;</span>
-      </h2>
-      <p>{children}</p>
-    </a>
-  );
-}

+ 0 - 11
packages/ui/src/code.tsx

@@ -1,11 +0,0 @@
-import { type JSX } from "react";
-
-export function Code({
-  children,
-  className,
-}: {
-  children: React.ReactNode;
-  className?: string;
-}): JSX.Element {
-  return <code className={className}>{children}</code>;
-}

+ 0 - 8
packages/ui/tsconfig.json

@@ -1,8 +0,0 @@
-{
-  "extends": "@repo/typescript-config/react-library.json",
-  "compilerOptions": {
-    "outDir": "dist"
-  },
-  "include": ["src"],
-  "exclude": ["node_modules", "dist"]
-}

文件差異過大導致無法顯示
+ 1403 - 533
pnpm-lock.yaml