├── e2e ├── .gitignore ├── .eslintrc ├── jest.config.js ├── system-db.ts ├── 9-cleaning │ └── 00-clean.test.ts ├── package.json ├── tsconfig.json └── jest-sequencer.js ├── web ├── src │ ├── utils │ │ ├── .gitkeep │ │ ├── getAvatarUrl.ts │ │ ├── getRegionById.ts │ │ └── getPageInfo.ts │ ├── constants │ │ └── .gitkeep │ ├── vite-env.d.ts │ ├── types │ │ └── index.d.ts │ ├── components │ │ ├── DateRangePicker │ │ │ └── index.css │ │ ├── EditableTable │ │ │ └── index.module.scss │ │ ├── Content │ │ │ └── index.tsx │ │ ├── Markdown │ │ │ └── formatLinkText.ts │ │ ├── IconText │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── DependenceList │ │ │ └── index.module.scss │ │ ├── Editor │ │ │ └── index.scss │ │ ├── Panel │ │ │ ├── index.module.scss │ │ │ └── index.tsx │ │ ├── TextButton │ │ │ └── index.tsx │ │ ├── SectionList │ │ │ └── index.module.scss │ │ ├── FileUpload │ │ │ └── index.module.scss │ │ └── ColorModeSwitch │ │ │ └── index.tsx │ ├── pages │ │ ├── app │ │ │ ├── setting │ │ │ │ ├── index.css │ │ │ │ ├── UserSetting │ │ │ │ │ ├── CardRedemption │ │ │ │ │ │ └── service.ts │ │ │ │ │ └── PATList │ │ │ │ │ │ └── DateSelector │ │ │ │ │ │ └── index.module.scss │ │ │ │ └── SysSetting │ │ │ │ │ └── AppEnvList │ │ │ │ │ └── EditTextarea │ │ │ │ │ └── index.tsx │ │ │ ├── functions │ │ │ │ └── mods │ │ │ │ │ ├── FunctionPanel │ │ │ │ │ ├── index.css │ │ │ │ │ └── ContextMenu │ │ │ │ │ │ └── index.scss │ │ │ │ │ └── HeadPanel │ │ │ │ │ └── index.css │ │ │ ├── storages │ │ │ │ └── mods │ │ │ │ │ └── index.module.scss │ │ │ ├── database │ │ │ │ ├── CollectionDataList │ │ │ │ │ └── mods │ │ │ │ │ │ ├── DataPanel │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ └── ColPanel │ │ │ │ │ │ └── index.tsx │ │ │ │ ├── mods │ │ │ │ │ └── AddRulesModal │ │ │ │ │ │ └── policyTemplate.ts │ │ │ │ └── BottomPanel │ │ │ │ │ └── index.tsx │ │ │ └── mods │ │ │ │ └── SideBar │ │ │ │ └── index.module.scss │ │ ├── homepage │ │ │ ├── video.tsx │ │ │ ├── status.module.scss │ │ │ ├── homepage.css │ │ │ ├── circle.tsx │ │ │ ├── contact.tsx │ │ │ ├── status.tsx │ │ │ └── index.tsx │ │ └── home │ │ │ ├── mods │ │ │ ├── Empty │ │ │ │ └── index.module.scss │ │ │ └── CreateAppModal │ │ │ │ ├── RuntimeItem │ │ │ │ └── index.tsx │ │ │ │ └── BundleItem │ │ │ │ └── index.tsx │ │ │ └── service.ts │ ├── layouts │ │ └── Auth │ │ │ └── index.module.scss │ ├── hooks │ │ ├── useDB.ts │ │ └── useCustomToast.ts │ └── apis │ │ └── dependence.ts ├── .env.production ├── public │ ├── robots.txt │ ├── bg.png │ ├── logo.png │ ├── favicon.ico │ ├── logo_light.png │ ├── logo_text.png │ ├── pwa-64x64.png │ ├── homepage │ │ ├── bg.png │ │ ├── p1.png │ │ ├── p2.png │ │ ├── p3.png │ │ ├── p4.png │ │ ├── p5.png │ │ ├── banner.png │ │ ├── database.png │ │ ├── function.png │ │ ├── icon_06.png │ │ ├── laficon.jpg │ │ ├── logo_text.png │ │ ├── storage.png │ │ ├── videobg.png │ │ ├── videomobile.png │ │ ├── Vector.svg │ │ ├── icon_02.svg │ │ ├── logo_icon.svg │ │ ├── icon_03.svg │ │ ├── icon_05.svg │ │ ├── cancel_btn.svg │ │ └── play.svg │ ├── masked-icon.png │ ├── pwa-192x192.png │ ├── pwa-512x512.png │ ├── apple-touch-icon.png │ ├── fonts │ │ └── NotoSansSC-Medium.ttf │ └── js │ │ └── monaco-editor.0.43.0 │ │ └── base │ │ ├── browser │ │ └── ui │ │ │ └── codicons │ │ │ └── codicon │ │ │ └── codicon.ttf │ │ └── common │ │ └── worker │ │ └── simpleWorker.nls.js ├── .dockerignore ├── .stylelintrc.json ├── .eslintrc ├── Dockerfile ├── postcss.config.cjs ├── tsconfig.node.json ├── .env ├── .swagger.config.js ├── .gitignore └── index.html ├── docs ├── .eslintignore ├── en │ ├── architecture.md │ └── ide.png ├── public │ ├── CNAME │ └── logo.png ├── .gitignore ├── .eslintrc ├── zh │ ├── doc-images │ │ ├── db.png │ │ ├── AppID.png │ │ ├── file.png │ │ ├── index.png │ │ ├── mj-id.png │ │ ├── add-env.png │ │ ├── add-pat.png │ │ ├── appList.png │ │ ├── dblist.jpg │ │ ├── doc-db.png │ │ ├── upload.png │ │ ├── Laf-Pilot.png │ │ ├── Laf-Pilot2.png │ │ ├── add-polocy.png │ │ ├── app-list.png │ │ ├── bind-pay.png │ │ ├── bind-pay2.png │ │ ├── cli-mind.png │ │ ├── doc-policy.png │ │ ├── function.png │ │ ├── new-logs-1.jpg │ │ ├── old-logs.jpg │ │ ├── register.png │ │ ├── todo-demo.png │ │ ├── SALAI_TOKEN.jpg │ │ ├── add-packages.png │ │ ├── auto-build1.png │ │ ├── auto-build2.png │ │ ├── creat-polocy.png │ │ ├── creat-token.png │ │ ├── doc-app-list.png │ │ ├── doc-storage.png │ │ ├── function-log.png │ │ ├── function-url.png │ │ ├── my-template.png │ │ ├── open-website.png │ │ ├── oss-get-sts.png │ │ ├── package-list.png │ │ ├── pakcage-list.jpg │ │ ├── use-injector.png │ │ ├── add-env-step1.png │ │ ├── add-env-step2.png │ │ ├── add-env-step3.png │ │ ├── create-bucket-1.png │ │ ├── create-bucket.png │ │ ├── create-function.jpg │ │ ├── create-function.png │ │ ├── create-gather.png │ │ ├── create-injector.png │ │ ├── create-laf-app.jpg │ │ ├── delete-package.png │ │ ├── function-body.png │ │ ├── function-market.png │ │ ├── function-query.png │ │ ├── polocy-db-data.png │ │ ├── set-wechat-pay.png │ │ ├── slack-connect.jpg │ │ ├── specification.jpg │ │ ├── web-ide-index.png │ │ ├── website-hosting.png │ │ ├── application-list.png │ │ ├── doc-function-list.png │ │ ├── function-template.png │ │ ├── run-cloudfunction.png │ │ ├── slack-create-app.jpg │ │ ├── slack-install-bot.jpg │ │ ├── create-application.png │ │ ├── create-cloudfunction.png │ │ ├── edit-cloudfunction.png │ │ ├── getToken-parseToken.png │ │ ├── slack-connect-create.jpg │ │ ├── slack-create-app-bot.jpg │ │ ├── change-package-version.png │ │ ├── publish-cloudfunction.png │ │ ├── sealos-website-hosting.png │ │ ├── select-package-version.png │ │ ├── slack-connect-create-1.jpg │ │ ├── MediaPlatformBaseSetting.png │ │ └── MediaPlatformBaseSetting2.png │ ├── overview-ide.png │ ├── cloud-function │ │ ├── env.png │ │ ├── cron.png │ │ └── cron.md │ ├── cloud-database │ │ ├── collection.png │ │ └── database-ql │ │ │ ├── dblist.jpg │ │ │ └── del.md │ ├── cloud-storage │ │ ├── website-hosting-0.png │ │ ├── website-hosting-domain.png │ │ ├── delete.md │ │ └── website-hosting.md │ └── examples │ │ └── index.md ├── Dockerfile ├── .vitepress │ ├── theme │ │ ├── index.ts │ │ └── custom.css │ └── en.mts └── scripts │ └── check-version.js ├── runtimes ├── python │ └── TBD.md └── nodejs │ ├── .eslintrc │ ├── .gitignore │ ├── src │ ├── support │ │ ├── engine │ │ │ └── index.ts │ │ ├── types.ts │ │ ├── logger.ts │ │ ├── database-change-stream │ │ │ └── website-hosting-change-stream.ts │ │ └── init-hook.ts │ └── constants.ts │ ├── .dockerignore │ ├── Dockerfile.init │ ├── functions │ └── tsconfig.json │ ├── start.sh │ ├── build-image.sh │ └── Dockerfile ├── server ├── src │ ├── i18n │ │ ├── en │ │ │ ├── subscription.json │ │ │ ├── notification.json │ │ │ └── function.json │ │ ├── zh │ │ │ ├── subscription.json │ │ │ ├── notification.json │ │ │ └── function.json │ │ └── zh-CN │ │ │ ├── subscription.json │ │ │ ├── notification.json │ │ │ └── function.json │ ├── app.service.ts │ ├── notification │ │ ├── notification-type.ts │ │ ├── notification.module.ts │ │ └── entities │ │ │ └── notification.ts │ ├── storage │ │ ├── minio │ │ │ └── types.ts │ │ ├── entities │ │ │ ├── minio.ts │ │ │ ├── storage-user.ts │ │ │ └── storage-bucket.ts │ │ └── dto │ │ │ ├── update-bucket.dto.ts │ │ │ └── create-bucket.dto.ts │ ├── database │ │ ├── entities │ │ │ ├── database-sync-record.ts │ │ │ └── collection.ts │ │ ├── dto │ │ │ ├── update-dedicated-database.dto.ts │ │ │ ├── update-policy.dto.ts │ │ │ ├── create-policy.dto.ts │ │ │ ├── update-rule.dto.ts │ │ │ ├── import-database.dto.ts │ │ │ ├── create-collection.dto.ts │ │ │ ├── update-collection.dto.ts │ │ │ ├── create-rule.dto.ts │ │ │ ├── update-dedicated-database-state.dto.ts │ │ │ └── create-dedicated-database.dto.ts │ │ └── listeners │ │ │ └── application.listener.ts │ ├── group │ │ ├── group-role.decorator.ts │ │ ├── dto │ │ │ ├── create-group.dto.ts │ │ │ ├── update-group.dto.ts │ │ │ ├── update-group-member-role.dto.ts │ │ │ ├── find-group-member.dto.ts │ │ │ ├── find-group-invite-code.dto.ts │ │ │ ├── update-group-invite-code.dto.ts │ │ │ └── get-group-invite-code-detail.dto.ts │ │ └── entities │ │ │ ├── group-application.ts │ │ │ ├── group.ts │ │ │ ├── group-invite-code.ts │ │ │ └── group-member.ts │ ├── user │ │ ├── dto │ │ │ ├── update-avatar.dto.ts │ │ │ ├── bind-username.dto.ts │ │ │ ├── bind-email.dto.ts │ │ │ └── create-pat.dto.ts │ │ ├── entities │ │ │ ├── user-avatar.ts │ │ │ ├── user-password.ts │ │ │ ├── pat.ts │ │ │ ├── user.ts │ │ │ ├── user-profile.ts │ │ │ └── user-quota.ts │ │ └── user.module.ts │ ├── recycle-bin │ │ ├── entities │ │ │ └── recycle-bin.ts │ │ └── cloud-function │ │ │ ├── interface │ │ │ └── function-recycle-bin-query.interface.ts │ │ │ └── dto │ │ │ ├── delete-recycle-bin-functions.dto.ts │ │ │ └── restore-recycle-bin-functions.dto.ts │ ├── authentication │ │ ├── jwt.auth.guard.ts │ │ ├── dto │ │ │ ├── github-signin.dto.ts │ │ │ ├── github-jump-login.dto.ts │ │ │ ├── pat2token.dto.ts │ │ │ ├── passwd-check.dto.ts │ │ │ ├── github-bind.dto.ts │ │ │ ├── email-verify-code.dto.ts │ │ │ ├── send-email-code.dto.ts │ │ │ ├── passwd-signin.dto.ts │ │ │ └── send-phone-code.dto.ts │ │ └── entities │ │ │ ├── auth-provider.ts │ │ │ ├── types.ts │ │ │ ├── email-verify-code.ts │ │ │ └── sms-verify-code.ts │ ├── billing │ │ ├── interface │ │ │ └── billing-query.interface.ts │ │ ├── dto │ │ │ └── billings.dto.ts │ │ └── entities │ │ │ └── network-traffic.ts │ ├── trigger │ │ ├── dto │ │ │ ├── update-trigger.dto.ts │ │ │ └── create-trigger.dto.ts │ │ └── entities │ │ │ └── cron-trigger.ts │ ├── initializer │ │ ├── deploy-manifest │ │ │ ├── databaseOpsRequestStart.yaml │ │ │ ├── databaseOpsRequestStop.yaml │ │ │ ├── databaseOpsRequestRestart.yaml │ │ │ ├── databaseOpsRequestHorizontalScaling.yaml │ │ │ ├── databaseOpsRequestVolumeExpansion.yaml │ │ │ └── databaseOpsRequestVerticalScaling.yaml │ │ └── initializer.module.ts │ ├── function-template │ │ ├── dto │ │ │ ├── function-template-usedBy.dto.ts │ │ │ └── use-function-template.dto.ts │ │ └── function-template.module.ts │ ├── utils │ │ ├── crypto.ts │ │ ├── interface.ts │ │ └── decorator.ts │ ├── website │ │ ├── dto │ │ │ ├── update-website.dto.ts │ │ │ └── create-website.dto.ts │ │ ├── website.module.ts │ │ └── entities │ │ │ └── website.ts │ ├── dependency │ │ ├── dto │ │ │ ├── delete-dependency.dto.ts │ │ │ ├── create-dependency.dto.ts │ │ │ └── update-dependency.dto.ts │ │ └── dependency.module.ts │ ├── account │ │ ├── interface │ │ │ └── account-query.interface.ts │ │ ├── entities │ │ │ ├── account-gift-code.ts │ │ │ ├── account-charge-reward.ts │ │ │ ├── payment-channel.ts │ │ │ ├── account-transaction.ts │ │ │ └── account.ts │ │ ├── dto │ │ │ ├── use-gift-code.dto.ts │ │ │ └── invite-code.dto.ts │ │ └── account.module.ts │ ├── function │ │ ├── dto │ │ │ ├── update-function-debug.dto.ts │ │ │ └── compile-function.dto.ts │ │ ├── entities │ │ │ └── cloud-function-history.ts │ │ └── function.module.ts │ ├── setting │ │ ├── setting.module.ts │ │ └── setting.service.ts │ ├── interceptor │ │ ├── interceptor.module.ts │ │ └── dto │ │ │ └── http-interceptor.dto.ts │ ├── application │ │ ├── dto │ │ │ ├── create-env.dto.ts │ │ │ ├── pod.dto.ts │ │ │ └── create-application.dto.ts │ │ ├── events │ │ │ ├── application-creating.event.ts │ │ │ └── application-bundle-updating.event.ts │ │ ├── bundle.service.ts │ │ └── entities │ │ │ └── runtime.ts │ ├── region │ │ ├── region.module.ts │ │ ├── cluster │ │ │ └── cluster.service.spec.ts │ │ └── region.controller.ts │ ├── log │ │ ├── entities │ │ │ └── function-log.ts │ │ └── log.module.ts │ ├── gateway │ │ └── entities │ │ │ └── bucket-domain.ts │ ├── monitor │ │ └── monitor.module.ts │ ├── instance │ │ └── instance.module.ts │ ├── app.controller.ts │ └── generated │ │ └── i18n.generated.ts ├── .dockerignore ├── .eslintrc ├── tsconfig.build.json ├── build-image.sh ├── test │ ├── jest-e2e.json │ └── app.e2e-spec.ts ├── nest-cli.json ├── .gitignore └── tsconfig.json ├── cli ├── .npmignore ├── .eslintrc ├── template │ ├── gitignore │ └── package.json └── src │ ├── util │ ├── print.ts │ ├── sys.ts │ └── format.ts │ ├── action │ ├── policy │ │ └── dto.ts │ ├── storage │ │ └── s3.ts │ └── environment │ │ └── index.ts │ ├── common │ ├── prompts.ts │ ├── wait.ts │ └── hook.ts │ ├── api │ ├── pat.ts │ ├── custom.ts │ └── v1 │ │ └── monitor.ts │ └── command │ ├── deploy │ └── index.ts │ ├── application │ └── index.ts │ ├── environment │ └── index.ts │ └── database │ └── index.ts ├── packages ├── client-sdk │ ├── .npmignore │ ├── .eslintrc │ ├── src │ │ ├── request │ │ │ └── index.ts │ │ └── index-bundle.ts │ ├── tests │ │ ├── http │ │ │ ├── config.js │ │ │ ├── read_test.js │ │ │ └── add_test.js │ │ └── units │ │ │ └── cloud_test.js │ └── webpack.config.js ├── cloud-sdk │ ├── .npmignore │ ├── .eslintrc │ ├── src │ │ ├── util.ts │ │ └── index.ts │ └── README.md ├── database-ql │ ├── .npmignore │ ├── .eslintrc │ ├── src │ │ ├── geo │ │ │ ├── index.ts │ │ │ └── interface.ts │ │ └── serverDate │ │ │ └── index.ts │ └── tests │ │ └── units │ │ └── get │ │ ├── orderby.test.js │ │ └── page.test.js ├── database-proxy │ ├── .eslintrc │ ├── src │ │ ├── policy │ │ │ └── index.ts │ │ ├── accessor │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── dbi │ │ │ ├── index.ts │ │ │ └── request.ts │ │ └── validators │ │ │ ├── index.ts │ │ │ └── lookup │ │ │ └── index.ts │ ├── .npmignore │ ├── docs │ │ ├── todo.md │ │ ├── ruler_v2_design.md │ │ └── rules-v2.json │ └── tests │ │ ├── units │ │ ├── policy │ │ │ └── rules.json │ │ └── accessor.test.js │ │ ├── mongo_db │ │ └── _db.js │ │ └── mysql_db │ │ └── _db.js ├── eslint-config-laf │ ├── .eslintrc │ ├── docs.js │ ├── service.js │ ├── test.js │ ├── runtime.js │ ├── cli.js │ └── server.js ├── node-modules-utils │ ├── .eslintrc │ ├── src │ │ └── index.ts │ ├── copy2app.sh │ ├── README.md │ └── tests │ │ ├── cloud-sdk.test.js │ │ └── import.test.js └── run-tests.sh ├── services └── runtime-exporter │ ├── .eslintrc │ ├── .gitignore │ ├── Dockerfile │ ├── src │ └── logger.ts │ ├── tsconfig.json │ └── tsconfig.dev.json ├── .husky └── pre-commit ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ └── config.yml ├── no-response.yml ├── stale.yml ├── actions │ └── build-docs │ │ └── action.yml ├── gh-bot.yml ├── FUNDING.yml └── workflows │ └── build-scripts-updated.yml ├── .vscode └── extensions.json ├── .lycheeignore ├── lerna.json └── .gitignore /e2e/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | -------------------------------------------------------------------------------- /web/src/utils/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.eslintignore: -------------------------------------------------------------------------------- 1 | public -------------------------------------------------------------------------------- /web/src/constants/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/en/architecture.md: -------------------------------------------------------------------------------- 1 | 2 | > TBD -------------------------------------------------------------------------------- /docs/public/CNAME: -------------------------------------------------------------------------------- 1 | lafjs.github.io -------------------------------------------------------------------------------- /runtimes/python/TBD.md: -------------------------------------------------------------------------------- 1 | 2 | > TBD -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | .vitepress/cache -------------------------------------------------------------------------------- /server/src/i18n/en/subscription.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /server/src/i18n/zh/subscription.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /web/.env.production: -------------------------------------------------------------------------------- 1 | VITE_SERVER_BASE_URL= -------------------------------------------------------------------------------- /server/.dockerignore: -------------------------------------------------------------------------------- 1 | 2 | .env.local 3 | .env -------------------------------------------------------------------------------- /server/src/i18n/zh-CN/subscription.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /web/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / -------------------------------------------------------------------------------- /web/.dockerignore: -------------------------------------------------------------------------------- 1 | # node_modules 2 | .env.local 3 | .env -------------------------------------------------------------------------------- /cli/.npmignore: -------------------------------------------------------------------------------- 1 | ./node_modules 2 | .DS_Store 3 | src 4 | tests -------------------------------------------------------------------------------- /web/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /cli/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/cli" 4 | } -------------------------------------------------------------------------------- /e2e/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/test" 4 | } -------------------------------------------------------------------------------- /web/.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { "extends": ["stylelint-config-standard"] } -------------------------------------------------------------------------------- /docs/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/docs" 4 | } -------------------------------------------------------------------------------- /server/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/server" 4 | } -------------------------------------------------------------------------------- /web/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/web" 4 | } 5 | -------------------------------------------------------------------------------- /docs/en/ide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/en/ide.png -------------------------------------------------------------------------------- /packages/client-sdk/.npmignore: -------------------------------------------------------------------------------- 1 | ./node_modules 2 | .DS_Store 3 | src 4 | tests -------------------------------------------------------------------------------- /packages/cloud-sdk/.npmignore: -------------------------------------------------------------------------------- 1 | ./node_modules 2 | .DS_Store 3 | src 4 | tests -------------------------------------------------------------------------------- /web/src/types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module "vscode/service-override/files"; 2 | -------------------------------------------------------------------------------- /packages/database-ql/.npmignore: -------------------------------------------------------------------------------- 1 | ./node_modules 2 | .DS_Store 3 | ./src 4 | ./tests -------------------------------------------------------------------------------- /runtimes/nodejs/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/runtime" 4 | } -------------------------------------------------------------------------------- /web/public/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/bg.png -------------------------------------------------------------------------------- /cli/template/gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .app.yaml 3 | package-lock.json 4 | laf.yaml 5 | -------------------------------------------------------------------------------- /docs/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/public/logo.png -------------------------------------------------------------------------------- /packages/client-sdk/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/package" 4 | } -------------------------------------------------------------------------------- /packages/cloud-sdk/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/package" 4 | } -------------------------------------------------------------------------------- /packages/database-ql/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/package" 4 | } -------------------------------------------------------------------------------- /web/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/logo.png -------------------------------------------------------------------------------- /packages/cloud-sdk/src/util.ts: -------------------------------------------------------------------------------- 1 | export const IS_SEALAF = process.env.IS_SEALAF === 'true' 2 | -------------------------------------------------------------------------------- /packages/database-proxy/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/package" 4 | } -------------------------------------------------------------------------------- /services/runtime-exporter/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/service" 4 | } -------------------------------------------------------------------------------- /web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/favicon.ico -------------------------------------------------------------------------------- /docs/zh/doc-images/db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/db.png -------------------------------------------------------------------------------- /docs/zh/overview-ide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/overview-ide.png -------------------------------------------------------------------------------- /packages/eslint-config-laf/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "./package.js" 4 | } -------------------------------------------------------------------------------- /packages/eslint-config-laf/docs.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: './package.js', 3 | } 4 | -------------------------------------------------------------------------------- /packages/eslint-config-laf/service.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: './server.js', 3 | } 4 | -------------------------------------------------------------------------------- /packages/eslint-config-laf/test.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: './package.js', 3 | } 4 | -------------------------------------------------------------------------------- /packages/node-modules-utils/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "laf/package" 4 | } -------------------------------------------------------------------------------- /services/runtime-exporter/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .env 4 | tsconfig.build.json 5 | -------------------------------------------------------------------------------- /web/public/logo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/logo_light.png -------------------------------------------------------------------------------- /web/public/logo_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/logo_text.png -------------------------------------------------------------------------------- /web/public/pwa-64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/pwa-64x64.png -------------------------------------------------------------------------------- /docs/zh/doc-images/AppID.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/AppID.png -------------------------------------------------------------------------------- /docs/zh/doc-images/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/file.png -------------------------------------------------------------------------------- /docs/zh/doc-images/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/index.png -------------------------------------------------------------------------------- /docs/zh/doc-images/mj-id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/mj-id.png -------------------------------------------------------------------------------- /web/public/homepage/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/bg.png -------------------------------------------------------------------------------- /web/public/homepage/p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/p1.png -------------------------------------------------------------------------------- /web/public/homepage/p2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/p2.png -------------------------------------------------------------------------------- /web/public/homepage/p3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/p3.png -------------------------------------------------------------------------------- /web/public/homepage/p4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/p4.png -------------------------------------------------------------------------------- /web/public/homepage/p5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/p5.png -------------------------------------------------------------------------------- /web/public/masked-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/masked-icon.png -------------------------------------------------------------------------------- /web/public/pwa-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/pwa-192x192.png -------------------------------------------------------------------------------- /web/public/pwa-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/pwa-512x512.png -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npm run lint-staged 5 | -------------------------------------------------------------------------------- /docs/zh/cloud-function/env.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/cloud-function/env.png -------------------------------------------------------------------------------- /docs/zh/doc-images/add-env.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/add-env.png -------------------------------------------------------------------------------- /docs/zh/doc-images/add-pat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/add-pat.png -------------------------------------------------------------------------------- /docs/zh/doc-images/appList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/appList.png -------------------------------------------------------------------------------- /docs/zh/doc-images/dblist.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/dblist.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/doc-db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/doc-db.png -------------------------------------------------------------------------------- /docs/zh/doc-images/upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/upload.png -------------------------------------------------------------------------------- /packages/database-proxy/src/policy/index.ts: -------------------------------------------------------------------------------- 1 | export * from './interface' 2 | export * from './policy' 3 | -------------------------------------------------------------------------------- /web/public/homepage/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/banner.png -------------------------------------------------------------------------------- /docs/zh/cloud-function/cron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/cloud-function/cron.png -------------------------------------------------------------------------------- /docs/zh/doc-images/Laf-Pilot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/Laf-Pilot.png -------------------------------------------------------------------------------- /docs/zh/doc-images/Laf-Pilot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/Laf-Pilot2.png -------------------------------------------------------------------------------- /docs/zh/doc-images/add-polocy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/add-polocy.png -------------------------------------------------------------------------------- /docs/zh/doc-images/app-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/app-list.png -------------------------------------------------------------------------------- /docs/zh/doc-images/bind-pay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/bind-pay.png -------------------------------------------------------------------------------- /docs/zh/doc-images/bind-pay2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/bind-pay2.png -------------------------------------------------------------------------------- /docs/zh/doc-images/cli-mind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/cli-mind.png -------------------------------------------------------------------------------- /docs/zh/doc-images/doc-policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/doc-policy.png -------------------------------------------------------------------------------- /docs/zh/doc-images/function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/function.png -------------------------------------------------------------------------------- /docs/zh/doc-images/new-logs-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/new-logs-1.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/old-logs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/old-logs.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/register.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/register.png -------------------------------------------------------------------------------- /docs/zh/doc-images/todo-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/todo-demo.png -------------------------------------------------------------------------------- /web/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/apple-touch-icon.png -------------------------------------------------------------------------------- /web/public/homepage/database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/database.png -------------------------------------------------------------------------------- /web/public/homepage/function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/function.png -------------------------------------------------------------------------------- /web/public/homepage/icon_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/icon_06.png -------------------------------------------------------------------------------- /web/public/homepage/laficon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/laficon.jpg -------------------------------------------------------------------------------- /web/public/homepage/logo_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/logo_text.png -------------------------------------------------------------------------------- /web/public/homepage/storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/storage.png -------------------------------------------------------------------------------- /web/public/homepage/videobg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/videobg.png -------------------------------------------------------------------------------- /docs/zh/doc-images/SALAI_TOKEN.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/SALAI_TOKEN.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/add-packages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/add-packages.png -------------------------------------------------------------------------------- /docs/zh/doc-images/auto-build1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/auto-build1.png -------------------------------------------------------------------------------- /docs/zh/doc-images/auto-build2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/auto-build2.png -------------------------------------------------------------------------------- /docs/zh/doc-images/creat-polocy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/creat-polocy.png -------------------------------------------------------------------------------- /docs/zh/doc-images/creat-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/creat-token.png -------------------------------------------------------------------------------- /docs/zh/doc-images/doc-app-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/doc-app-list.png -------------------------------------------------------------------------------- /docs/zh/doc-images/doc-storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/doc-storage.png -------------------------------------------------------------------------------- /docs/zh/doc-images/function-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/function-log.png -------------------------------------------------------------------------------- /docs/zh/doc-images/function-url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/function-url.png -------------------------------------------------------------------------------- /docs/zh/doc-images/my-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/my-template.png -------------------------------------------------------------------------------- /docs/zh/doc-images/open-website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/open-website.png -------------------------------------------------------------------------------- /docs/zh/doc-images/oss-get-sts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/oss-get-sts.png -------------------------------------------------------------------------------- /docs/zh/doc-images/package-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/package-list.png -------------------------------------------------------------------------------- /docs/zh/doc-images/pakcage-list.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/pakcage-list.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/use-injector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/use-injector.png -------------------------------------------------------------------------------- /web/public/homepage/videomobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/homepage/videomobile.png -------------------------------------------------------------------------------- /docs/zh/cloud-database/collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/cloud-database/collection.png -------------------------------------------------------------------------------- /docs/zh/doc-images/add-env-step1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/add-env-step1.png -------------------------------------------------------------------------------- /docs/zh/doc-images/add-env-step2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/add-env-step2.png -------------------------------------------------------------------------------- /docs/zh/doc-images/add-env-step3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/add-env-step3.png -------------------------------------------------------------------------------- /docs/zh/doc-images/create-bucket-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/create-bucket-1.png -------------------------------------------------------------------------------- /docs/zh/doc-images/create-bucket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/create-bucket.png -------------------------------------------------------------------------------- /docs/zh/doc-images/create-function.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/create-function.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/create-function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/create-function.png -------------------------------------------------------------------------------- /docs/zh/doc-images/create-gather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/create-gather.png -------------------------------------------------------------------------------- /docs/zh/doc-images/create-injector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/create-injector.png -------------------------------------------------------------------------------- /docs/zh/doc-images/create-laf-app.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/create-laf-app.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/delete-package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/delete-package.png -------------------------------------------------------------------------------- /docs/zh/doc-images/function-body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/function-body.png -------------------------------------------------------------------------------- /docs/zh/doc-images/function-market.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/function-market.png -------------------------------------------------------------------------------- /docs/zh/doc-images/function-query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/function-query.png -------------------------------------------------------------------------------- /docs/zh/doc-images/polocy-db-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/polocy-db-data.png -------------------------------------------------------------------------------- /docs/zh/doc-images/set-wechat-pay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/set-wechat-pay.png -------------------------------------------------------------------------------- /docs/zh/doc-images/slack-connect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/slack-connect.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/specification.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/specification.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/web-ide-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/web-ide-index.png -------------------------------------------------------------------------------- /docs/zh/doc-images/website-hosting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/website-hosting.png -------------------------------------------------------------------------------- /web/public/fonts/NotoSansSC-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/fonts/NotoSansSC-Medium.ttf -------------------------------------------------------------------------------- /docs/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bitnami/openresty:latest 2 | 3 | WORKDIR /app 4 | EXPOSE 8080 5 | 6 | ADD ./.vitepress/dist /app/ 7 | -------------------------------------------------------------------------------- /docs/zh/doc-images/application-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/application-list.png -------------------------------------------------------------------------------- /docs/zh/doc-images/doc-function-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/doc-function-list.png -------------------------------------------------------------------------------- /docs/zh/doc-images/function-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/function-template.png -------------------------------------------------------------------------------- /docs/zh/doc-images/run-cloudfunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/run-cloudfunction.png -------------------------------------------------------------------------------- /docs/zh/doc-images/slack-create-app.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/slack-create-app.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/slack-install-bot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/slack-install-bot.jpg -------------------------------------------------------------------------------- /server/src/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common' 2 | 3 | @Injectable() 4 | export class AppService {} 5 | -------------------------------------------------------------------------------- /docs/zh/cloud-storage/website-hosting-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/cloud-storage/website-hosting-0.png -------------------------------------------------------------------------------- /docs/zh/doc-images/create-application.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/create-application.png -------------------------------------------------------------------------------- /docs/zh/doc-images/create-cloudfunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/create-cloudfunction.png -------------------------------------------------------------------------------- /docs/zh/doc-images/edit-cloudfunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/edit-cloudfunction.png -------------------------------------------------------------------------------- /docs/zh/doc-images/getToken-parseToken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/getToken-parseToken.png -------------------------------------------------------------------------------- /docs/zh/doc-images/slack-connect-create.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/slack-connect-create.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/slack-create-app-bot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/slack-create-app-bot.jpg -------------------------------------------------------------------------------- /packages/database-proxy/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | .nyc_output 4 | .DS_Store 5 | DS_Store 6 | src 7 | tests 8 | docs -------------------------------------------------------------------------------- /web/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:alpine 2 | 3 | COPY ./nginx.conf /etc/nginx/conf.d/default.conf 4 | COPY ./dist /usr/share/nginx/html 5 | -------------------------------------------------------------------------------- /web/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import DefaultTheme from 'vitepress/theme' 2 | import './custom.css' 3 | 4 | export default DefaultTheme -------------------------------------------------------------------------------- /docs/zh/cloud-database/database-ql/dblist.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/cloud-database/database-ql/dblist.jpg -------------------------------------------------------------------------------- /docs/zh/doc-images/change-package-version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/change-package-version.png -------------------------------------------------------------------------------- /docs/zh/doc-images/publish-cloudfunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/publish-cloudfunction.png -------------------------------------------------------------------------------- /docs/zh/doc-images/sealos-website-hosting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/sealos-website-hosting.png -------------------------------------------------------------------------------- /docs/zh/doc-images/select-package-version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/select-package-version.png -------------------------------------------------------------------------------- /docs/zh/doc-images/slack-connect-create-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/slack-connect-create-1.jpg -------------------------------------------------------------------------------- /server/src/notification/notification-type.ts: -------------------------------------------------------------------------------- 1 | export enum NotificationType { 2 | InsufficientBalance = 'InsufficientBalance', 3 | } 4 | -------------------------------------------------------------------------------- /docs/zh/cloud-storage/website-hosting-domain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/cloud-storage/website-hosting-domain.png -------------------------------------------------------------------------------- /docs/zh/doc-images/MediaPlatformBaseSetting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/MediaPlatformBaseSetting.png -------------------------------------------------------------------------------- /docs/zh/doc-images/MediaPlatformBaseSetting2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/docs/zh/doc-images/MediaPlatformBaseSetting2.png -------------------------------------------------------------------------------- /packages/client-sdk/src/request/index.ts: -------------------------------------------------------------------------------- 1 | export * from './request' 2 | export * from './request-uni' 3 | export * from './request-wxmp' 4 | -------------------------------------------------------------------------------- /packages/database-proxy/src/accessor/index.ts: -------------------------------------------------------------------------------- 1 | export * from './accessor' 2 | 3 | export * from './mongo' 4 | 5 | export * from './mysql' 6 | -------------------------------------------------------------------------------- /packages/node-modules-utils/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './package' 2 | export * from './declaration' 3 | export * from './import-parser' 4 | -------------------------------------------------------------------------------- /packages/run-tests.sh: -------------------------------------------------------------------------------- 1 | docker run --rm -p 27018:27017 --name mongotest -d mongo 2 | npx mocha ./*/tests/**/*.test.js 3 | docker rm -f mongotest -------------------------------------------------------------------------------- /server/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /web/src/components/DateRangePicker/index.css: -------------------------------------------------------------------------------- 1 | .rdp-day_selected { 2 | background-color: #00a9a6 !important; 3 | color: white !important; 4 | } 5 | -------------------------------------------------------------------------------- /runtimes/nodejs/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | 4 | upload 5 | data/* 6 | tmp 7 | 8 | .env 9 | 10 | ecosystem.config.js 11 | .DS_Store 12 | -------------------------------------------------------------------------------- /cli/src/util/print.ts: -------------------------------------------------------------------------------- 1 | import * as emoji from 'node-emoji' 2 | 3 | export function getEmoji(value: any) { 4 | return emoji.get(emoji.find(value).key) 5 | } 6 | -------------------------------------------------------------------------------- /server/src/i18n/zh/notification.json: -------------------------------------------------------------------------------- 1 | { 2 | "InsufficientBalance": { 3 | "title": "laf 账户欠费", 4 | "content": "你的账户已欠费,应用 {appid} 将停止运行,请及时充值" 5 | } 6 | } -------------------------------------------------------------------------------- /server/src/storage/minio/types.ts: -------------------------------------------------------------------------------- 1 | export type MinioCommandExecOutput = { 2 | status: 'success' | 'error' 3 | error?: any 4 | [key: string]: any 5 | } 6 | -------------------------------------------------------------------------------- /cli/template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laf-app", 3 | "description": "the app engine service of lat", 4 | "dependencies": {}, 5 | "devDependencies": {} 6 | } -------------------------------------------------------------------------------- /server/src/i18n/zh-CN/notification.json: -------------------------------------------------------------------------------- 1 | { 2 | "InsufficientBalance": { 3 | "title": "laf 账户欠费", 4 | "content": "你的账户已欠费,应用 {appid} 将停止运行,请及时充值" 5 | } 6 | } -------------------------------------------------------------------------------- /docs/zh/cloud-function/cron.md: -------------------------------------------------------------------------------- 1 | 2 | # 定时任务 3 | 4 | 本节介绍使用触发器,定时触发云函数的执行。 5 | 6 | ![Cron Trigger](cron.png) 7 | 8 | 如图,在「应用开发控制台」中,云函数编辑器页面左上触,可打开触发器管理面板,按界面操作即可新建定时触发器来实现定时任务。 -------------------------------------------------------------------------------- /runtimes/nodejs/src/support/engine/index.ts: -------------------------------------------------------------------------------- 1 | export * from './cache' 2 | 3 | export * from './executor' 4 | 5 | export * from './types' 6 | 7 | export * from './console' 8 | -------------------------------------------------------------------------------- /web/src/components/EditableTable/index.module.scss: -------------------------------------------------------------------------------- 1 | .text { 2 | white-space: nowrap; 3 | overflow: hidden; 4 | text-overflow: ellipsis; 5 | font-family: Inter; 6 | } 7 | -------------------------------------------------------------------------------- /web/src/pages/app/setting/index.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable selector-class-pattern */ 2 | .chakra-modal__content-container::-webkit-scrollbar { 3 | width: 0; 4 | height: 0; 5 | } -------------------------------------------------------------------------------- /server/src/database/entities/database-sync-record.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | 3 | export class DatabaseSyncRecord { 4 | uid: ObjectId 5 | createdAt: Date 6 | } 7 | -------------------------------------------------------------------------------- /web/src/utils/getAvatarUrl.ts: -------------------------------------------------------------------------------- 1 | export function getAvatarUrl(uid?: string, updatedAt?: string) { 2 | return `${window.location.origin}/v1/user/avatar/${uid}?t=${updatedAt}`; 3 | } 4 | -------------------------------------------------------------------------------- /server/src/group/group-role.decorator.ts: -------------------------------------------------------------------------------- 1 | import { SetMetadata } from '@nestjs/common' 2 | 3 | export const GroupRoles = (...roles: string[]) => 4 | SetMetadata('group-roles', roles) 5 | -------------------------------------------------------------------------------- /web/src/pages/app/functions/mods/FunctionPanel/index.css: -------------------------------------------------------------------------------- 1 | .funcList .simplebar-scrollbar::before { 2 | background: #dee0e2; 3 | width: 4px; 4 | transform: translateX(100%); 5 | } 6 | -------------------------------------------------------------------------------- /web/src/pages/app/functions/mods/HeadPanel/index.css: -------------------------------------------------------------------------------- 1 | .recentList .simplebar-scrollbar::before { 2 | background: #dee0e2; 3 | height: 6px; 4 | transform: translateY(50%); 5 | } 6 | -------------------------------------------------------------------------------- /web/src/pages/app/storages/mods/index.module.scss: -------------------------------------------------------------------------------- 1 | .circle::before { 2 | display: inline-block; 3 | width: 8px; 4 | height: 8px; 5 | border-radius: 50%; 6 | margin-right: 4px; 7 | } 8 | -------------------------------------------------------------------------------- /runtimes/nodejs/src/support/types.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express' 2 | 3 | export interface IRequest extends Request { 4 | user?: any 5 | requestId?: string 6 | [key: string]: any 7 | } 8 | -------------------------------------------------------------------------------- /web/src/pages/app/database/CollectionDataList/mods/DataPanel/index.module.scss: -------------------------------------------------------------------------------- 1 | .simplebar-scrollbar::before { 2 | background: #7b838b; 3 | width: 4px; 4 | transform: translateX(100%); 5 | } 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [!{node_modules}/**] 4 | end_of_line = lf 5 | charset = utf-8 6 | insert_final_newline = true 7 | 8 | [{*.js,*.ts}] 9 | indent_style = space 10 | indent_size = 2 -------------------------------------------------------------------------------- /web/public/js/monaco-editor.0.43.0/base/browser/ui/codicons/codicon/codicon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/labring/laf/HEAD/web/public/js/monaco-editor.0.43.0/base/browser/ui/codicons/codicon/codicon.ttf -------------------------------------------------------------------------------- /server/src/user/dto/update-avatar.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | 3 | export class UpdateAvatarDto { 4 | @ApiProperty({ type: 'string', format: 'binary' }) 5 | avatar: any 6 | } 7 | -------------------------------------------------------------------------------- /server/src/recycle-bin/entities/recycle-bin.ts: -------------------------------------------------------------------------------- 1 | export enum DataType { 2 | FUNCTION = 'function', 3 | } 4 | 5 | export class RecycleBin { 6 | type: DataType 7 | data: any 8 | createdAt: Date 9 | } 10 | -------------------------------------------------------------------------------- /docs/zh/examples/index.md: -------------------------------------------------------------------------------- 1 | 2 | # laf 使用实例 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ## 云存储 11 | - [微信小程序上传文件](/zh/examples/wxmp-upload.md) 12 | - [用 GitHub Action 自动构建前端并发布到网站托管](/zh/examples/website-hosting-ci-cd.md) -------------------------------------------------------------------------------- /packages/database-proxy/docs/todo.md: -------------------------------------------------------------------------------- 1 | 2 | ### 规则相关 3 | 4 | #### 1. 将规则测试用例拆到单独的测试文件中,不断完善每种规则的测试覆盖 5 | 6 | #### 2. query 规则为数组时,缺少相关测试用例,此功能尚未验证可用性 7 | 8 | ### 代码优化 9 | 10 | #### 1. 给 ruler 和 validator 代码添加丰富的注释 -------------------------------------------------------------------------------- /server/src/authentication/jwt.auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common' 2 | import { AuthGuard } from '@nestjs/passport' 3 | 4 | @Injectable() 5 | export class JwtAuthGuard extends AuthGuard('jwt') {} 6 | -------------------------------------------------------------------------------- /packages/client-sdk/tests/http/config.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | dbProxyUrl: 3 | 'https://6217ba84-5f56-45b1-a46b-7fb69a7ea1e9.lafyun.com/proxy/app', 4 | getAccessToken: () => '', 5 | } 6 | 7 | module.exports = config 8 | -------------------------------------------------------------------------------- /server/src/database/dto/update-dedicated-database.dto.ts: -------------------------------------------------------------------------------- 1 | import { CreateDedicatedDatabaseDto } from './create-dedicated-database.dto' 2 | 3 | export class UpdateDedicatedDatabaseDto extends CreateDedicatedDatabaseDto {} 4 | -------------------------------------------------------------------------------- /server/src/billing/interface/billing-query.interface.ts: -------------------------------------------------------------------------------- 1 | export interface BillingQuery { 2 | appid?: string[] 3 | startTime?: Date 4 | endTime?: Date 5 | page?: number 6 | pageSize?: number 7 | state?: string 8 | } 9 | -------------------------------------------------------------------------------- /packages/database-ql/src/geo/index.ts: -------------------------------------------------------------------------------- 1 | export * from './point' 2 | export * from './lineString' 3 | export * from './polygon' 4 | export * from './multiPoint' 5 | export * from './multiLineString' 6 | export * from './multiPolygon' 7 | -------------------------------------------------------------------------------- /server/src/trigger/dto/update-trigger.dto.ts: -------------------------------------------------------------------------------- 1 | import { PartialType } from '@nestjs/swagger' 2 | import { CreateTriggerDto } from './create-trigger.dto' 3 | 4 | export class UpdateTriggerDto extends PartialType(CreateTriggerDto) {} 5 | -------------------------------------------------------------------------------- /packages/database-proxy/tests/units/policy/rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": { 3 | "read": true, 4 | "update": true, 5 | "$schema": { 6 | "account": { "match": "^\\d{6,10}$" } 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /e2e/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'node', 5 | testSequencer: './jest-sequencer.js', 6 | maxWorkers: 1, 7 | verbose: true, 8 | } 9 | -------------------------------------------------------------------------------- /server/src/storage/entities/minio.ts: -------------------------------------------------------------------------------- 1 | export class MinioUser { 2 | accessKey: string 3 | policyName: string 4 | userStatus: 'enabled' | 'disabled' 5 | memberOf: { 6 | name: string 7 | policies: string[] 8 | }[] 9 | } 10 | -------------------------------------------------------------------------------- /web/src/pages/app/database/mods/AddRulesModal/policyTemplate.ts: -------------------------------------------------------------------------------- 1 | const policyTemplate = { 2 | read: true, 3 | count: true, 4 | update: false, 5 | remove: false, 6 | add: false, 7 | }; 8 | 9 | export default policyTemplate; 10 | -------------------------------------------------------------------------------- /server/build-image.sh: -------------------------------------------------------------------------------- 1 | # Warning: just for development phase, will be move to github action in future. 2 | 3 | 4 | 5 | docker buildx build --platform linux/amd64,linux/arm64 --push -t docker.io/lafyun/laf-server:debug-202306151521 -f Dockerfile . 6 | -------------------------------------------------------------------------------- /server/src/i18n/en/notification.json: -------------------------------------------------------------------------------- 1 | { 2 | "InsufficientBalance": { 3 | "title": "Laf account is in arrears", 4 | "content": "Your account is in arrears, the app {appid} will stop running, please recharge your account promptly!" 5 | } 6 | } -------------------------------------------------------------------------------- /packages/cloud-sdk/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Cloud } from './cloud' 2 | 3 | export * from './cloud.interface' 4 | export * from './function.interface' 5 | export * from './cloud' 6 | 7 | const cloud = new Cloud() 8 | 9 | export default cloud 10 | -------------------------------------------------------------------------------- /server/test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /web/src/components/Content/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function Content(props: { children: React.ReactNode }) { 4 | return
{props.children}
; 5 | } 6 | -------------------------------------------------------------------------------- /cli/src/action/policy/dto.ts: -------------------------------------------------------------------------------- 1 | interface PolicyRule { 2 | collectionName: string 3 | rules: Rules 4 | } 5 | 6 | interface Rules { 7 | read: boolean 8 | count: boolean 9 | update: boolean 10 | remove: boolean 11 | add: boolean 12 | } 13 | -------------------------------------------------------------------------------- /packages/database-proxy/tests/mongo_db/_db.js: -------------------------------------------------------------------------------- 1 | const dbconfig = { 2 | dbName: 'testdb', 3 | url: 'mongodb://localhost:27018', 4 | connSettings: { 5 | directConnection: true, 6 | }, 7 | } 8 | 9 | module.exports = { 10 | dbconfig, 11 | } 12 | -------------------------------------------------------------------------------- /server/src/initializer/deploy-manifest/databaseOpsRequestStart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.kubeblocks.io/v1alpha1 2 | kind: OpsRequest 3 | metadata: 4 | name: <%- name %> 5 | namespace: laf-system 6 | spec: 7 | clusterRef: <%- clusterName %> 8 | type: Start 9 | -------------------------------------------------------------------------------- /server/src/initializer/deploy-manifest/databaseOpsRequestStop.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.kubeblocks.io/v1alpha1 2 | kind: OpsRequest 3 | metadata: 4 | name: <%- name %> 5 | namespace: laf-system 6 | spec: 7 | clusterRef: <%- clusterName %> 8 | type: Stop 9 | -------------------------------------------------------------------------------- /web/src/layouts/Auth/index.module.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | height: 100vh; 3 | width: 100vw; 4 | background-image: url("@/assets/login_bg.svg"); 5 | background-repeat: no-repeat; 6 | background-position: left bottom; 7 | background-size: 56%; 8 | } 9 | -------------------------------------------------------------------------------- /server/src/billing/dto/billings.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | 3 | export class BillingsByDayDto { 4 | @ApiProperty({ type: String }) 5 | totalAmount: number 6 | 7 | @ApiProperty({ type: Date }) 8 | day: Date 9 | } 10 | -------------------------------------------------------------------------------- /server/src/function-template/dto/function-template-usedBy.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { ObjectId } from 'mongodb' 3 | 4 | export class GetFunctionTemplateUsedByDto { 5 | @ApiProperty({ type: String }) 6 | uid: ObjectId 7 | } 8 | -------------------------------------------------------------------------------- /cli/src/common/prompts.ts: -------------------------------------------------------------------------------- 1 | import * as prompts from 'prompts' 2 | 3 | export async function confirm(message: string) { 4 | return await prompts({ 5 | type: 'confirm', 6 | name: 'value', 7 | message: message, 8 | initial: false, 9 | }) 10 | } 11 | -------------------------------------------------------------------------------- /runtimes/nodejs/.dockerignore: -------------------------------------------------------------------------------- 1 | # node_modules 2 | .env 3 | ecosystem.config.js 4 | # dist 5 | data 6 | # src 7 | tests 8 | commitlint.config.js 9 | ecosystem.config.js.tpl 10 | .DS_Store 11 | .env.development 12 | .env.production 13 | .gitignore 14 | Dockerfile 15 | http -------------------------------------------------------------------------------- /server/src/database/dto/update-policy.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString } from 'class-validator' 3 | export class UpdatePolicyDto { 4 | @ApiProperty() 5 | @IsNotEmpty() 6 | @IsString() 7 | injector: string 8 | } 9 | -------------------------------------------------------------------------------- /server/src/recycle-bin/cloud-function/interface/function-recycle-bin-query.interface.ts: -------------------------------------------------------------------------------- 1 | export interface CloudFunctionRecycleBinQuery { 2 | name?: string 3 | appid?: string 4 | startTime?: Date 5 | endTime?: Date 6 | page?: number 7 | pageSize?: number 8 | } 9 | -------------------------------------------------------------------------------- /runtimes/nodejs/Dockerfile.init: -------------------------------------------------------------------------------- 1 | FROM node:20.10.0 2 | 3 | WORKDIR /app 4 | 5 | COPY ./init.sh /app/init.sh 6 | COPY ./upload-dependencies.sh /app/upload-dependencies.sh 7 | 8 | RUN chown -R node:node /app 9 | 10 | USER node 11 | 12 | CMD [ "sh", "/app/init.sh" ] 13 | -------------------------------------------------------------------------------- /server/src/utils/crypto.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from 'crypto' 2 | 3 | // use sha256 to hash the password 4 | export function hashPassword(password: string): string { 5 | const hash = crypto.createHash('sha256') 6 | hash.update(password) 7 | return hash.digest('hex') 8 | } 9 | -------------------------------------------------------------------------------- /web/src/components/Markdown/formatLinkText.ts: -------------------------------------------------------------------------------- 1 | export const formatLinkText = (text: string) => { 2 | const httpReg = 3 | /(http|https|ftp):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/gi; 4 | return text.replace(httpReg, ` $& `); 5 | }; 6 | -------------------------------------------------------------------------------- /server/src/database/dto/create-policy.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString } from 'class-validator' 3 | 4 | export class CreatePolicyDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @IsString() 8 | name: string 9 | } 10 | -------------------------------------------------------------------------------- /web/public/homepage/Vector.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/src/utils/getRegionById.ts: -------------------------------------------------------------------------------- 1 | import { TRegion } from "@/apis/typing"; 2 | 3 | function getRegionById(regions: TRegion[] | undefined, id: string): TRegion | undefined { 4 | return (regions || []).find((region) => region._id === id); 5 | } 6 | 7 | export default getRegionById; 8 | -------------------------------------------------------------------------------- /packages/node-modules-utils/copy2app.sh: -------------------------------------------------------------------------------- 1 | rm -rf ../app-service/node_modules/node-modules-utils/dist 2 | rm -rf ../app-service/node_modules/node-modules-utils/src 3 | cp -r dist ../app-service/node_modules/node-modules-utils/dist 4 | cp -r src ../app-service/node_modules/node-modules-utils/src -------------------------------------------------------------------------------- /server/src/authentication/dto/github-signin.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString } from 'class-validator' 3 | 4 | export class GithubSigninDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @IsString() 8 | code: string 9 | } 10 | -------------------------------------------------------------------------------- /server/src/website/dto/update-website.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString } from 'class-validator' 3 | 4 | export class BindCustomDomainDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @IsString() 8 | domain: string 9 | } 10 | -------------------------------------------------------------------------------- /cli/src/api/pat.ts: -------------------------------------------------------------------------------- 1 | import { request } from '../util/request' 2 | 3 | export async function pat2token(server: string, data: { pat: string }): Promise { 4 | return request({ 5 | url: server + `/v1/auth/pat2token`, 6 | method: 'POST', 7 | data: data, 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /packages/database-proxy/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './proxy' 2 | export * from './policy' 3 | export * from './accessor' 4 | export * from './types' 5 | export * from './processor' 6 | 7 | export * from './dbi' 8 | export * from './logger' 9 | 10 | export { Db } from 'database-ql' 11 | -------------------------------------------------------------------------------- /server/src/dependency/dto/delete-dependency.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, Length } from 'class-validator' 3 | 4 | export class DeleteDependencyDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @Length(1, 64) 8 | name: string 9 | } 10 | -------------------------------------------------------------------------------- /cli/src/command/deploy/index.ts: -------------------------------------------------------------------------------- 1 | import { Command, program } from 'commander' 2 | import { deploy } from '../../action/deploy' 3 | 4 | export function command(): Command { 5 | const cmd = program.command('deploy').action(() => { 6 | deploy() 7 | }) 8 | 9 | return cmd 10 | } 11 | -------------------------------------------------------------------------------- /server/src/authentication/dto/github-jump-login.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString } from 'class-validator' 3 | 4 | export class GithubJumpLoginDto { 5 | @ApiProperty() 6 | @IsString() 7 | @IsNotEmpty() 8 | redirectUri: string 9 | } 10 | -------------------------------------------------------------------------------- /packages/eslint-config-laf/runtime.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: './package.js', 3 | rules: { 4 | 'prettier/prettier': [ 5 | 'error', 6 | { 7 | singleQuote: true, 8 | trailingComma: 'all', 9 | semi: false, 10 | }, 11 | ], 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /server/src/group/dto/create-group.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString, Length } from 'class-validator' 3 | 4 | export class CreateGroupDto { 5 | @ApiProperty() 6 | @IsString() 7 | @IsNotEmpty() 8 | @Length(1, 64) 9 | name: string 10 | } 11 | -------------------------------------------------------------------------------- /server/src/group/dto/update-group.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString, Length } from 'class-validator' 3 | 4 | export class UpdateGroupDto { 5 | @ApiProperty() 6 | @IsString() 7 | @IsNotEmpty() 8 | @Length(1, 64) 9 | name: string 10 | } 11 | -------------------------------------------------------------------------------- /web/src/pages/homepage/video.tsx: -------------------------------------------------------------------------------- 1 | import { site_url } from "@/constants"; 2 | 3 | export default function Video() { 4 | return ( 5 | <> 6 | 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /cli/src/util/sys.ts: -------------------------------------------------------------------------------- 1 | import { ProjectSchema } from '../schema/project' 2 | 3 | export function getAppPath(): string { 4 | return process.cwd() 5 | } 6 | 7 | export function getBaseDir(): string { 8 | const projectSchema = ProjectSchema.read() 9 | return projectSchema?.spec?.baseDir || './' 10 | } 11 | -------------------------------------------------------------------------------- /packages/node-modules-utils/README.md: -------------------------------------------------------------------------------- 1 | # `node-modules-utils` 2 | 3 | > 用于加载、解析项目本地 node_modules 中依赖的信息, 用于 `less-framework` 中, 主要用来获取包的 Typescript 类型文件,供 Web IDE 在线类型提示和补全使用。 4 | 5 | ## Usage 6 | 7 | ``` 8 | const nmUtils = require('node-modules-utils'); 9 | 10 | // TODO: DEMONSTRATE API 11 | ``` 12 | -------------------------------------------------------------------------------- /server/src/account/interface/account-query.interface.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | 3 | export interface AccountChargeOrderQuery { 4 | phase?: string 5 | id?: ObjectId 6 | startTime?: Date 7 | endTime?: Date 8 | page?: number 9 | pageSize?: number 10 | channel?: string 11 | } 12 | -------------------------------------------------------------------------------- /packages/database-proxy/src/dbi/index.ts: -------------------------------------------------------------------------------- 1 | import { AccessorInterface } from '../accessor' 2 | import { Db } from 'database-ql' 3 | import { Request } from './request' 4 | 5 | export function getDb(accessor: AccessorInterface): Db { 6 | return new Db({ 7 | request: new Request(accessor), 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /runtimes/nodejs/functions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "noUnusedLocals": false, 5 | "noUnusedParameters": false, 6 | "baseUrl": "./", 7 | "paths": { 8 | "@/*": ["./*"] 9 | } 10 | }, 11 | "include": [ 12 | "./*" 13 | ] 14 | } -------------------------------------------------------------------------------- /server/src/database/dto/update-rule.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsJSON, IsNotEmpty, MaxLength } from 'class-validator' 3 | 4 | export class UpdatePolicyRuleDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @MaxLength(2048) 8 | @IsJSON() 9 | value: string 10 | } 11 | -------------------------------------------------------------------------------- /server/src/database/dto/import-database.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | 3 | export class ImportDatabaseDto { 4 | @ApiProperty({ type: 'binary', format: 'binary' }) 5 | file: any 6 | 7 | @ApiProperty({ type: 'string', description: 'source appid' }) 8 | sourceAppid: string 9 | } 10 | -------------------------------------------------------------------------------- /server/src/function/dto/update-function-debug.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsObject } from 'class-validator' 3 | 4 | export class UpdateFunctionDebugDto { 5 | @ApiProperty() 6 | @IsObject() 7 | params: any 8 | 9 | validate() { 10 | return null 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /server/src/initializer/deploy-manifest/databaseOpsRequestRestart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.kubeblocks.io/v1alpha1 2 | kind: OpsRequest 3 | metadata: 4 | name: <%- name %> 5 | namespace: laf-system 6 | spec: 7 | clusterRef: <%- clusterName %> 8 | type: Restart 9 | restart: 10 | - componentName: mongodb 11 | -------------------------------------------------------------------------------- /web/src/components/IconText/index.module.scss: -------------------------------------------------------------------------------- 1 | .iconText { 2 | color: #7b838b; 3 | 4 | svg { 5 | fill: #7b838b !important; 6 | } 7 | 8 | &:hover { 9 | color: var(--chakra-colors-grayModern-600); 10 | svg { 11 | fill: var(--chakra-colors-grayModern-600) !important; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /server/src/setting/setting.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common' 2 | import { SettingService } from './setting.service' 3 | import { SettingController } from './setting.controller' 4 | 5 | @Module({ 6 | providers: [SettingService], 7 | controllers: [SettingController], 8 | }) 9 | export class SettingModule {} 10 | -------------------------------------------------------------------------------- /web/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "composite": true, 5 | "module": "ESNext", 6 | "skipLibCheck": true, 7 | "moduleResolution": "Node", 8 | "allowSyntheticDefaultImports": true, 9 | "types": ["node"] 10 | }, 11 | "include": ["vite.config.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /runtimes/nodejs/src/support/logger.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: Maslow 3 | * @Date: 2021-07-30 10:30:29 4 | * @LastEditTime: 2021-10-06 19:26:58 5 | * @Description: 6 | */ 7 | 8 | import { Console } from './engine' 9 | 10 | /** 11 | * The global logger instance 12 | */ 13 | export const logger = new Console('#') 14 | -------------------------------------------------------------------------------- /server/src/account/entities/account-gift-code.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | 3 | export class GiftCode { 4 | _id?: ObjectId 5 | code: string 6 | creditAmount: number 7 | used: boolean 8 | usedBy?: ObjectId 9 | usedAt?: Date 10 | createdAt: Date 11 | expiredAt?: Date 12 | transactionId?: ObjectId 13 | } 14 | -------------------------------------------------------------------------------- /docs/scripts/check-version.js: -------------------------------------------------------------------------------- 1 | // Lock lockFileVersion to version 2 And resolve import error when import xxx from 'node:xxx' 2 | if (process.version && +process.version.slice(1).split('.')[0] < 18) { 3 | console.log( 4 | `Required node version >= 18 not satisfied with current version ${process.version}.` 5 | ) 6 | process.exit(1) 7 | } 8 | -------------------------------------------------------------------------------- /server/src/account/dto/use-gift-code.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, Length } from 'class-validator' 3 | 4 | export class UseGiftCodeDto { 5 | @ApiProperty({ 6 | description: 'gift code', 7 | type: 'string', 8 | }) 9 | @IsNotEmpty() 10 | @Length(8, 64) 11 | code: string 12 | } 13 | -------------------------------------------------------------------------------- /server/src/database/dto/create-collection.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, Length } from 'class-validator' 3 | 4 | export class CreateCollectionDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @Length(3, 32) 8 | name: string 9 | 10 | async validate() { 11 | return null 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /server/src/group/dto/update-group-member-role.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEnum } from 'class-validator' 2 | import { GroupRole } from '../entities/group-member' 3 | import { ApiProperty } from '@nestjs/swagger' 4 | 5 | export class UpdateGroupMemberRoleDto { 6 | @ApiProperty({ enum: GroupRole }) 7 | @IsEnum(GroupRole) 8 | role: GroupRole 9 | } 10 | -------------------------------------------------------------------------------- /server/src/storage/dto/update-bucket.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsEnum } from 'class-validator' 3 | import { BucketPolicy } from '../entities/storage-bucket' 4 | 5 | export class UpdateBucketDto { 6 | @ApiProperty({ enum: BucketPolicy }) 7 | @IsEnum(BucketPolicy) 8 | policy: BucketPolicy 9 | } 10 | -------------------------------------------------------------------------------- /server/src/user/entities/user-avatar.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { ObjectId } from 'mongodb' 3 | 4 | export class UserAvatar { 5 | @ApiProperty({ type: Buffer }) 6 | data: Buffer 7 | 8 | @ApiProperty({ type: String }) 9 | createdBy: ObjectId 10 | 11 | @ApiProperty() 12 | createdAt: Date 13 | } 14 | -------------------------------------------------------------------------------- /web/.env: -------------------------------------------------------------------------------- 1 | # keep it default "" in both dev or prod environment unless you must use a custom server api 2 | VITE_SERVER_BASE_URL= 3 | 4 | # this only used for dev environment, change it to your local api server url if needed 5 | # don't change it directly, you should create a .env.local file and set it there 6 | VITE_DEV_SERVER_URL=http://api.laf.run 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Join Our Discord 4 | url: https://discord.gg/uWZqAwwdvy 5 | about: Join our community, we will keep you in the loop. 6 | - name: Contact US / Business Inquiries 7 | url: https://docs.qq.com/form/page/DS0tCWXpQc2NpR3dR 8 | about: Please contact us. -------------------------------------------------------------------------------- /packages/eslint-config-laf/cli.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: './package.js', 3 | rules: { 4 | 'prettier/prettier': [ 5 | 'error', 6 | { 7 | singleQuote: true, 8 | trailingComma: 'all', 9 | semi: false, 10 | printWidth: 120, 11 | tabWidth: 2, 12 | }, 13 | ], 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /server/src/function/dto/compile-function.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString } from 'class-validator' 3 | 4 | export class CompileFunctionDto { 5 | @ApiProperty({ 6 | description: 'The source code of the function', 7 | }) 8 | @IsNotEmpty() 9 | @IsString() 10 | code: string 11 | } 12 | -------------------------------------------------------------------------------- /packages/database-proxy/tests/mysql_db/_db.js: -------------------------------------------------------------------------------- 1 | // docker run --name mysqldb -e MYSQL_ROOT_PASSWORD=kissme -e MYSQL_DATABASE=testdb -d -p 3306:3306 mysql 2 | const dbconfig = { 3 | db: 'testdb', 4 | user: 'root', 5 | password: 'kissme', 6 | host: 'localhost', 7 | port: 3306, 8 | connectionLimit: 30, 9 | } 10 | 11 | module.exports = dbconfig 12 | -------------------------------------------------------------------------------- /web/.swagger.config.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | swaggerPath: "http://api.maslow-dev.lafyun.com/-json", 4 | typingFileName: "api-auto.d.ts", 5 | 6 | outDir: "src/apis/v1", 7 | request: "import request from '@/utils/request';", 8 | fileNameRule: function (url) { 9 | return url.split("/")[2]; 10 | }, 11 | }, 12 | ]; 13 | -------------------------------------------------------------------------------- /e2e/system-db.ts: -------------------------------------------------------------------------------- 1 | import { Config } from './config' 2 | import { MongoClient } from 'mongodb' 3 | 4 | export async function getDbClient() { 5 | const client = new MongoClient(Config.MONGO_URI) 6 | await client.connect() 7 | return client 8 | } 9 | 10 | export async function getDb() { 11 | const client = await getDbClient() 12 | return client.db() 13 | } 14 | -------------------------------------------------------------------------------- /packages/cloud-sdk/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | > @lafjs/cloud is used in cloud function, exposing resource objects to cloud function. 5 | 6 | ```ts 7 | import cloud from '@lafjs/cloud' 8 | 9 | exports.main = async function (ctx) { 10 | 11 | const db = cloud.database() 12 | const res = await db.collection('messages').get() 13 | 14 | return res.data 15 | } 16 | ``` -------------------------------------------------------------------------------- /server/src/group/dto/find-group-member.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { OmitType } from '@nestjs/mapped-types' 3 | import { GroupMember } from '../entities/group-member' 4 | 5 | export class FindGroupMemberDto extends OmitType(GroupMember, [ 6 | 'groupId', 7 | '_id', 8 | ]) { 9 | @ApiProperty() 10 | username: string 11 | } 12 | -------------------------------------------------------------------------------- /server/src/user/entities/user-password.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | 3 | export enum UserPasswordState { 4 | Active = 'Active', 5 | Inactive = 'Inactive', 6 | } 7 | 8 | export class UserPassword { 9 | _id?: ObjectId 10 | uid: ObjectId 11 | password: string 12 | state: UserPasswordState 13 | createdAt: Date 14 | updatedAt: Date 15 | } 16 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "christian-kohler.npm-intellisense", 5 | "streetsidesoftware.code-spell-checker", 6 | "pomdtr.excalidraw-editor", 7 | "Tim-Koehler.helm-intellisense", 8 | "lokalise.i18n-ally", 9 | "stylelint.vscode-stylelint", 10 | "EditorConfig.EditorConfig" 11 | ] 12 | } -------------------------------------------------------------------------------- /server/src/database/dto/update-collection.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiPropertyOptional } from '@nestjs/swagger' 2 | import { IsObject, IsString } from 'class-validator' 3 | 4 | export class UpdateCollectionDto { 5 | @ApiPropertyOptional() 6 | @IsObject() 7 | validatorSchema: object 8 | 9 | @ApiPropertyOptional() 10 | @IsString() 11 | validationLevel: string 12 | } 13 | -------------------------------------------------------------------------------- /server/src/dependency/dto/create-dependency.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, Length } from 'class-validator' 3 | 4 | export class CreateDependencyDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @Length(1, 64) 8 | name: string 9 | 10 | @ApiProperty() 11 | @IsNotEmpty() 12 | @Length(1, 64) 13 | spec: string 14 | } 15 | -------------------------------------------------------------------------------- /server/src/dependency/dto/update-dependency.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, Length } from 'class-validator' 3 | 4 | export class UpdateDependencyDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @Length(1, 64) 8 | name: string 9 | 10 | @ApiProperty() 11 | @IsNotEmpty() 12 | @Length(1, 64) 13 | spec: string 14 | } 15 | -------------------------------------------------------------------------------- /server/src/user/dto/bind-username.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString, Length } from 'class-validator' 3 | 4 | export class BindUsernameDto { 5 | @ApiProperty({ 6 | description: 'username', 7 | example: 'laf-user', 8 | }) 9 | @IsString() 10 | @IsNotEmpty() 11 | @Length(3, 64) 12 | username: string 13 | } 14 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | *.log 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | pnpm-debug.log* 7 | lerna-debug.log* 8 | 9 | node_modules 10 | dist 11 | dist-ssr 12 | dev-dist 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /server/src/interceptor/interceptor.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common' 2 | import { HttpInterceptorService } from './http-interceptor.service' 3 | import { HttpModule } from '@nestjs/axios' 4 | 5 | @Module({ 6 | imports: [HttpModule], 7 | providers: [HttpInterceptorService], 8 | exports: [HttpInterceptorService], 9 | }) 10 | export class InterceptorModule {} 11 | -------------------------------------------------------------------------------- /packages/client-sdk/src/index-bundle.ts: -------------------------------------------------------------------------------- 1 | import { init, Cloud, Db, EnvironmentType } from './index' 2 | 3 | export * from './index' 4 | 5 | // 此行是为了运行测试用例时, 报 window undefined 使用; 6 | // 如果浏览器环境因此报错, 需要注释掉本行; 7 | // var window: any 8 | 9 | if (window) { 10 | window['LafClient'] = { 11 | initLessClient: init, 12 | Cloud, 13 | Db, 14 | EnvironmentType, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /web/src/components/DependenceList/index.module.scss: -------------------------------------------------------------------------------- 1 | .dependenceList { 2 | max-height: 60vh; 3 | overflow: auto; 4 | 5 | li { 6 | cursor: pointer; 7 | display: flex; 8 | min-height: 80px; 9 | align-items: center; 10 | justify-content: space-between; 11 | padding: 5px 8px; 12 | 13 | span { 14 | vertical-align: middle; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /web/src/pages/homepage/status.module.scss: -------------------------------------------------------------------------------- 1 | .breathing-gradient { 2 | background: #5cdd8b; 3 | display: inline-block; 4 | border-radius: 50rem; 5 | width: 5px; 6 | height: 16px; 7 | margin-right: 2px; 8 | } 9 | 10 | @keyframes breathing { 11 | 0% { 12 | opacity: 0.6; 13 | } 14 | 50% { 15 | opacity: 1; 16 | } 17 | 100% { 18 | opacity: 0.6; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /web/src/utils/getPageInfo.ts: -------------------------------------------------------------------------------- 1 | import { PageValues } from "@/components/Pagination"; 2 | 3 | export default function getPageInfo(data: { 4 | pageSize: number; 5 | page: number; 6 | total: number; 7 | [key: string]: any; 8 | }): PageValues { 9 | return { 10 | pageSize: data?.pageSize, 11 | limit: data?.pageSize, 12 | page: data?.page, 13 | total: data?.total, 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /server/src/group/entities/group-application.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { ObjectId } from 'mongodb' 3 | 4 | export class GroupApplication { 5 | @ApiProperty({ type: 'string' }) 6 | _id?: ObjectId 7 | 8 | @ApiProperty({ type: 'string' }) 9 | groupId: ObjectId 10 | 11 | @ApiProperty() 12 | appid: string 13 | 14 | @ApiProperty() 15 | createdAt: Date 16 | } 17 | -------------------------------------------------------------------------------- /server/src/initializer/initializer.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common' 2 | import { RegionService } from 'src/region/region.service' 3 | import { MinioService } from 'src/storage/minio/minio.service' 4 | import { InitializerService } from './initializer.service' 5 | 6 | @Module({ 7 | providers: [InitializerService, MinioService, RegionService], 8 | }) 9 | export class InitializerModule {} 10 | -------------------------------------------------------------------------------- /.lycheeignore: -------------------------------------------------------------------------------- 1 | .*appid.* 2 | .*xx.* 3 | https://beian.miit.gov.cn/ 4 | .*127-0-0-1.* 5 | https://oss.laf.run 6 | https://github.com/labring/laf/edit/main/docs/ 7 | https://openapi.alipaydev.com/gateway.do 8 | https://github.com/labring/laf/commit/ 9 | https://github.com/labring/laf/issues/ 10 | https://twitter.com/laf_dev 11 | https://oss.laf.dev 12 | https://oss.laf.dev/ 13 | https://laf.run/v1/auth/passwd/signin -------------------------------------------------------------------------------- /docs/.vitepress/theme/custom.css: -------------------------------------------------------------------------------- 1 | .VPSidebar::-webkit-scrollbar { 2 | display: none; 3 | } 4 | 5 | /* 6 | .VPDocAside .outline-link { 7 | color: rgb(6, 63, 148); 8 | } 9 | 10 | .VPDocAside .outline-link { 11 | font-size: 14px; 12 | } 13 | 14 | .VPDocAside .outline-link.active { 15 | color: rgb(82, 7, 234); 16 | } 17 | 18 | 19 | .VPDocAside .outline-link:hover { 20 | color: rgb(82, 7, 234); 21 | } */ -------------------------------------------------------------------------------- /server/src/authentication/dto/pat2token.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString } from 'class-validator' 3 | 4 | export class Pat2TokenDto { 5 | @ApiProperty({ 6 | description: 'PAT', 7 | example: 8 | 'laf_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', 9 | }) 10 | @IsString() 11 | @IsNotEmpty() 12 | pat: string 13 | } 14 | -------------------------------------------------------------------------------- /web/src/components/Editor/index.scss: -------------------------------------------------------------------------------- 1 | .code .property { 2 | color: #A31515 3 | } 4 | 5 | .code .number { 6 | color: #01a99d 7 | } 8 | 9 | .code .string { 10 | color: #0451a5 11 | } 12 | 13 | [data-theme="dark"] .code .property { 14 | color: #9BDCFE 15 | } 16 | 17 | [data-theme="dark"] .code .number { 18 | color: #B0CAA4 19 | } 20 | 21 | [data-theme="dark"] .code .string { 22 | color: #CE9178 23 | } -------------------------------------------------------------------------------- /server/src/database/dto/create-rule.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsJSON, IsNotEmpty, IsString, MaxLength } from 'class-validator' 3 | 4 | export class CreatePolicyRuleDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @IsString() 8 | collectionName: string 9 | 10 | @ApiProperty() 11 | @IsNotEmpty() 12 | @MaxLength(2048) 13 | @IsJSON() 14 | value: string 15 | } 16 | -------------------------------------------------------------------------------- /server/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src", 5 | "compilerOptions": { 6 | "assets": [ 7 | { 8 | "include": "i18n/**/*", 9 | "watchAssets": true 10 | }, 11 | { 12 | "include": "initializer/deploy-manifest/*", 13 | "watchAssets": true 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /server/src/i18n/zh/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "create": { 3 | "nameExist": "函数 {name} 已存在", 4 | "maxCount": "达到函数最大数量 {max}", 5 | "error": "创建函数失败" 6 | }, 7 | "get": {}, 8 | "update": { 9 | "error": "更新函数失败" 10 | }, 11 | "delete": { 12 | "error": "删除函数失败" 13 | }, 14 | "compile": { 15 | "codeRequired": "函数代码不能为空" 16 | }, 17 | "common": { 18 | "notFound": "函数 {name} 不存在" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/authentication/dto/passwd-check.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString, Length } from 'class-validator' 3 | 4 | export class PasswdCheckDto { 5 | @ApiProperty({ 6 | description: 'username | phone | email', 7 | example: 'laf-user | 13805718888 | laf-user@laf.com', 8 | }) 9 | @IsString() 10 | @IsNotEmpty() 11 | @Length(3, 64) 12 | username: string 13 | } 14 | -------------------------------------------------------------------------------- /server/src/group/dto/find-group-invite-code.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { User } from 'src/user/entities/user' 3 | import { GroupInviteCode } from '../entities/group-invite-code' 4 | import { OmitType } from '@nestjs/mapped-types' 5 | 6 | export class FindGroupInviteCodeDto extends OmitType(GroupInviteCode, [ 7 | 'usedBy', 8 | ]) { 9 | @ApiProperty({ type: User }) 10 | usedBy: User 11 | } 12 | -------------------------------------------------------------------------------- /server/src/i18n/zh-CN/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "create": { 3 | "nameExist": "函数 {name} 已存在", 4 | "maxCount": "达到函数最大数量 {max}", 5 | "error": "创建函数失败" 6 | }, 7 | "get": {}, 8 | "update": { 9 | "error": "更新函数失败" 10 | }, 11 | "delete": { 12 | "error": "删除函数失败" 13 | }, 14 | "compile": { 15 | "codeRequired": "函数代码不能为空" 16 | }, 17 | "common": { 18 | "notFound": "函数 {name} 不存在" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/authentication/entities/auth-provider.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | 3 | export enum AuthProviderState { 4 | Enabled = 'Enabled', 5 | Disabled = 'Disabled', 6 | } 7 | 8 | export class AuthProvider { 9 | _id?: ObjectId 10 | name: string 11 | bind: any 12 | register: boolean 13 | default: boolean 14 | state: AuthProviderState 15 | config: any 16 | createdAt: Date 17 | updatedAt: Date 18 | } 19 | -------------------------------------------------------------------------------- /server/src/recycle-bin/cloud-function/dto/delete-recycle-bin-functions.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsArray, IsNotEmpty, IsString } from 'class-validator' 3 | 4 | export class DeleteRecycleBinItemsDto { 5 | @ApiProperty({ 6 | description: 'The list of item ids', 7 | type: [String], 8 | }) 9 | @IsNotEmpty() 10 | @IsArray() 11 | @IsString({ each: true }) 12 | ids: string[] 13 | } 14 | -------------------------------------------------------------------------------- /server/src/user/dto/bind-email.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsEmail, IsNotEmpty, Length } from 'class-validator' 3 | 4 | export class BindEmailDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @IsEmail() 8 | email: string 9 | 10 | @ApiProperty({ 11 | description: 'verify code', 12 | example: '032476', 13 | }) 14 | @IsNotEmpty() 15 | @Length(6, 6) 16 | code: string 17 | } 18 | -------------------------------------------------------------------------------- /server/src/recycle-bin/cloud-function/dto/restore-recycle-bin-functions.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsArray, IsNotEmpty, IsString } from 'class-validator' 3 | 4 | export class RestoreRecycleBinItemsDto { 5 | @ApiProperty({ 6 | description: 'The list of item ids', 7 | type: [String], 8 | }) 9 | @IsNotEmpty() 10 | @IsArray() 11 | @IsString({ each: true }) 12 | ids: string[] 13 | } 14 | -------------------------------------------------------------------------------- /server/src/utils/interface.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from 'express' 2 | import { Application } from 'src/application/entities/application' 3 | import { UserWithProfile } from 'src/user/entities/user' 4 | 5 | export interface IRequest extends Request { 6 | user?: UserWithProfile 7 | application?: Application 8 | [key: string]: any 9 | } 10 | 11 | export interface IResponse extends Response { 12 | [key: string]: any 13 | } 14 | -------------------------------------------------------------------------------- /server/src/database/dto/update-dedicated-database-state.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEnum, IsNotEmpty } from 'class-validator' 2 | import { DedicatedDatabaseState } from '../entities/dedicated-database' 3 | import { ApiProperty } from '@nestjs/swagger' 4 | 5 | export class UpdateDedicatedDatabaseStateDto { 6 | @ApiProperty({ enum: DedicatedDatabaseState }) 7 | @IsEnum(DedicatedDatabaseState) 8 | @IsNotEmpty() 9 | state: DedicatedDatabaseState 10 | } 11 | -------------------------------------------------------------------------------- /server/src/group/dto/update-group-invite-code.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsEnum, IsNotEmpty } from 'class-validator' 3 | import { GroupRole } from '../entities/group-member' 4 | import { ObjectId } from 'mongodb' 5 | 6 | export class GenerateGroupInviteCodeDto { 7 | @ApiProperty({ enum: GroupRole }) 8 | @IsEnum(GroupRole) 9 | @IsNotEmpty() 10 | role: GroupRole 11 | 12 | createdBy: ObjectId 13 | } 14 | -------------------------------------------------------------------------------- /server/src/application/dto/create-env.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString, Length, Matches } from 'class-validator' 3 | 4 | export class CreateEnvironmentDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @IsString() 8 | @Length(1, 64) 9 | @Matches(/^[a-zA-Z_][a-zA-Z0-9_]{1,64}$/) 10 | name: string 11 | 12 | @ApiProperty() 13 | @Length(0, 4096) 14 | @IsString() 15 | value: string 16 | } 17 | -------------------------------------------------------------------------------- /server/src/trigger/dto/create-trigger.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, Length } from 'class-validator' 3 | 4 | export class CreateTriggerDto { 5 | @ApiProperty() 6 | @IsNotEmpty() 7 | @Length(1, 64) 8 | desc: string 9 | 10 | @ApiProperty() 11 | @IsNotEmpty() 12 | @Length(1, 64) 13 | cron: string 14 | 15 | @ApiProperty() 16 | @IsNotEmpty() 17 | @Length(1, 255) 18 | target: string 19 | } 20 | -------------------------------------------------------------------------------- /server/src/website/dto/create-website.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsEnum, IsNotEmpty, IsString } from 'class-validator' 3 | import { DomainState } from 'src/gateway/entities/runtime-domain' 4 | 5 | export class CreateWebsiteDto { 6 | @ApiProperty() 7 | @IsNotEmpty() 8 | @IsString() 9 | bucketName: string 10 | 11 | @ApiProperty() 12 | @IsEnum(DomainState) 13 | @IsNotEmpty() 14 | state: DomainState 15 | } 16 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "./packages/*", 4 | "./docs", 5 | "./server", 6 | "./web", 7 | "./runtimes/nodejs", 8 | "./cli", 9 | "./services/*", 10 | "./e2e" 11 | ], 12 | "version": "1.0.0", 13 | "command": { 14 | "publish": { 15 | "ignoreChanges": [ 16 | "package-lock.json", 17 | "*.md", 18 | "tests", 19 | "http", 20 | "ecosystem.config*" 21 | ] 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /server/src/region/region.module.ts: -------------------------------------------------------------------------------- 1 | import { Global, Module } from '@nestjs/common' 2 | import { RegionService } from './region.service' 3 | import { RegionController } from './region.controller' 4 | import { ClusterService } from './cluster/cluster.service' 5 | 6 | @Global() 7 | @Module({ 8 | providers: [RegionService, ClusterService], 9 | controllers: [RegionController], 10 | exports: [RegionService, ClusterService], 11 | }) 12 | export class RegionModule {} 13 | -------------------------------------------------------------------------------- /cli/src/action/storage/s3.ts: -------------------------------------------------------------------------------- 1 | import { S3Client } from '@aws-sdk/client-s3' 2 | 3 | export function getS3ClientV3(credentials: any): S3Client { 4 | return new S3Client({ 5 | credentials: { 6 | accessKeyId: credentials.accessKeyId, 7 | secretAccessKey: credentials.accessKeySecret, 8 | sessionToken: credentials.sessionToken, 9 | }, 10 | endpoint: credentials.endpoint, 11 | forcePathStyle: true, 12 | region: 'us-east-1', 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /server/src/log/entities/function-log.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { ObjectId } from 'mongodb' 3 | 4 | export class FunctionLog { 5 | @ApiProperty({ type: String }) 6 | _id?: ObjectId 7 | 8 | @ApiProperty() 9 | request_id: string 10 | 11 | // cloud function name 12 | @ApiProperty() 13 | func: string 14 | 15 | // log content 16 | @ApiProperty() 17 | data: string 18 | 19 | @ApiProperty() 20 | created_at: Date 21 | } 22 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 云开发 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /web/src/pages/home/mods/Empty/index.module.scss: -------------------------------------------------------------------------------- 1 | .emptyItem { 2 | width: 230px; 3 | height: 78px; 4 | 5 | box-shadow: rgb(196 206 216 / 25%) 0px 4px 8px; 6 | border-radius: 24px 0px; 7 | margin-bottom: 24px; 8 | position: relative; 9 | 10 | &::before { 11 | content: " "; 12 | height: 10px; 13 | position: absolute; 14 | left: 20px; 15 | width: 4px; 16 | height: 16px; 17 | background: #00a99d; 18 | border-radius: 24px; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/zh/cloud-storage/delete.md: -------------------------------------------------------------------------------- 1 | 2 | # 在云函数中删除文件 3 | 4 | ::: tip 5 | 在云函数中操作云存储,需要提前创建一个存储桶(Bucket),以下示例使用 `data` 存储桶演示上传文件操作,请提前创建该存储桶。 6 | ::: 7 | 8 | ## 删除文件 9 | 10 | ```ts 11 | import cloud from '@lafjs/cloud' 12 | 13 | export default async function (ctx: FunctionContext) { 14 | // 获取存储桶 15 | const bucket = cloud.storage.bucket('data') 16 | 17 | // 删除文件 18 | await bucket.deleteFile('index.html') 19 | } 20 | ``` 21 | 22 | ::: tip 23 | 注意:如果文件不存在,也会正常返回,不会抛出异常。 24 | ::: 25 | -------------------------------------------------------------------------------- /server/src/database/entities/collection.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { Binary, CollectionInfo, Document } from 'mongodb' 3 | 4 | export class Collection implements CollectionInfo { 5 | @ApiProperty() 6 | name: string 7 | 8 | @ApiProperty() 9 | type?: string 10 | 11 | @ApiProperty() 12 | options?: Document 13 | 14 | @ApiProperty() 15 | info?: { readOnly?: false; uuid?: Binary } 16 | 17 | @ApiProperty() 18 | idIndex?: Document 19 | } 20 | -------------------------------------------------------------------------------- /services/runtime-exporter/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20.10.0 2 | 3 | # Set environment variables 4 | ENV LOG_LEVEL=debug 5 | ENV NODE_ENV=production 6 | 7 | WORKDIR /app 8 | 9 | COPY ./dist /app/dist 10 | COPY ./node_modules /app/node_modules 11 | COPY ./package*.json /app/ 12 | 13 | # Set non-root user for better security 14 | RUN chown -R node:node /app 15 | USER node 16 | 17 | # Expose application port 18 | EXPOSE 2342 19 | 20 | # Start the application 21 | CMD [ "npm", "run", "start" ] 22 | -------------------------------------------------------------------------------- /server/src/authentication/dto/github-bind.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator' 3 | 4 | export class GithubBind { 5 | @ApiProperty({ description: 'temporary token signed for github bindings' }) 6 | @IsString() 7 | @IsNotEmpty() 8 | token: string 9 | 10 | @ApiProperty({ description: 'Is a newly registered use' }) 11 | @IsBoolean() 12 | @IsOptional() 13 | isRegister: boolean 14 | } 15 | -------------------------------------------------------------------------------- /server/src/gateway/entities/bucket-domain.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | import { DomainPhase, DomainState } from './runtime-domain' 3 | 4 | export class BucketDomain { 5 | _id?: ObjectId 6 | appid: string 7 | bucketName: string 8 | domain: string 9 | state: DomainState 10 | phase: DomainPhase 11 | lockedAt: Date 12 | createdAt: Date 13 | updatedAt: Date 14 | 15 | constructor(partial: Partial) { 16 | Object.assign(this, partial) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /server/src/billing/entities/network-traffic.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | 3 | export class Traffic { 4 | _id?: ObjectId 5 | 6 | timestamp: Date 7 | 8 | traffic_meta: TrafficMeta 9 | 10 | recv_bytes: number 11 | 12 | sent_bytes: number 13 | } 14 | 15 | export class TrafficMeta { 16 | pod_address: string 17 | 18 | pod_name: string 19 | 20 | pod_namespace: string 21 | 22 | pod_type: number 23 | 24 | pod_type_name: string 25 | 26 | traffic_tag: string 27 | } 28 | -------------------------------------------------------------------------------- /server/src/dependency/dependency.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common' 2 | import { ApplicationModule } from 'src/application/application.module' 3 | import { DependencyController } from './dependency.controller' 4 | import { DependencyService } from './dependency.service' 5 | 6 | @Module({ 7 | imports: [ApplicationModule], 8 | controllers: [DependencyController], 9 | providers: [DependencyService], 10 | exports: [DependencyService], 11 | }) 12 | export class DependencyModule {} 13 | -------------------------------------------------------------------------------- /server/src/interceptor/dto/http-interceptor.dto.ts: -------------------------------------------------------------------------------- 1 | export enum HttpInterceptorAction { 2 | ALLOW = 'allow', 3 | DENY = 'deny', 4 | } 5 | class HttpInterceptorRewrite { 6 | status: number 7 | data: any 8 | } 9 | class HttpInterceptorRedirect { 10 | status: number 11 | data: string 12 | } 13 | export class HttpInterceptorResponseDto { 14 | action: HttpInterceptorAction 15 | rewrite?: HttpInterceptorRewrite 16 | redirect?: HttpInterceptorRedirect 17 | denyMessage?: string 18 | } 19 | -------------------------------------------------------------------------------- /docs/.vitepress/en.mts: -------------------------------------------------------------------------------- 1 | import { DefaultTheme } from 'vitepress' 2 | 3 | 4 | export const NavItemsInEnglish: DefaultTheme.NavItem[] = [ 5 | // { text: 'Guides', link: '/en/' }, 6 | // { text: 'Examples', link: './markdown-examples' } 7 | ] 8 | 9 | export const SidebarItemsInEnglish: DefaultTheme.SidebarItem[] = [ 10 | { 11 | text: 'Getting Started', 12 | items: [ 13 | { text: 'Overview', link: '/en/' }, 14 | { text: 'Architecture', link: '/en/architecture' }, 15 | ] 16 | } 17 | ] -------------------------------------------------------------------------------- /server/src/authentication/dto/email-verify-code.dto.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | 3 | export enum EmailVerifyCodeType { 4 | Bind = 'bind', 5 | Unbind = 'Unbind', 6 | } 7 | 8 | export enum EmailVerifyCodeState { 9 | Unused = 0, 10 | Used = 1, 11 | } 12 | 13 | export class EmailVerifyCode { 14 | _id?: ObjectId 15 | email: string 16 | code: string 17 | ip: string 18 | type: EmailVerifyCodeType 19 | state: EmailVerifyCodeState 20 | createdAt: Date 21 | updatedAt: Date 22 | } 23 | -------------------------------------------------------------------------------- /server/src/user/dto/create-pat.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { 3 | IsNotEmpty, 4 | IsNumber, 5 | IsString, 6 | Length, 7 | Max, 8 | Min, 9 | } from 'class-validator' 10 | 11 | export class CreatePATDto { 12 | @IsString() 13 | @IsNotEmpty() 14 | @Length(1, 255) 15 | @ApiProperty() 16 | name: string 17 | 18 | @IsNumber() 19 | @IsNotEmpty() 20 | @Min(60) 21 | @Max(3600 * 24 * 365) 22 | @ApiProperty({ minimum: 60 }) 23 | expiresIn: number 24 | } 25 | -------------------------------------------------------------------------------- /runtimes/nodejs/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ln -s $CUSTOM_DEPENDENCY_BASE_PATH/node_modules $PWD/functions/node_modules >/dev/null 2>&1 4 | 5 | # generate package.json 6 | # ( 7 | # cd $CUSTOM_DEPENDENCY_BASE_PATH 8 | # npm install $DEPENDENCIES $NPM_INSTALL_FLAGS > /dev/null 2>&1 9 | # ) 10 | 11 | # source .env 12 | echo "****** start service: node $FLAGS --experimental-vm-modules --experimental-fetch ./dist/index.js *******" 13 | exec node $FLAGS --experimental-vm-modules --experimental-fetch ./dist/index.js 14 | -------------------------------------------------------------------------------- /cli/src/util/format.ts: -------------------------------------------------------------------------------- 1 | import * as dayjs from 'dayjs' 2 | 3 | export function formatDate( 4 | date?: string | number | Date | dayjs.Dayjs | null | undefined, 5 | format = 'YYYY-MM-DD HH:mm:ss', 6 | ) { 7 | return dayjs(date).format(format) 8 | } 9 | 10 | export function formatSize(size: number) { 11 | const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] 12 | let i = 0 13 | while (size >= 1024) { 14 | size /= 1024 15 | i++ 16 | } 17 | return size.toFixed(2) + ' ' + units[i] 18 | } 19 | -------------------------------------------------------------------------------- /packages/database-proxy/tests/units/accessor.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | const { MongoAccessor } = require('../../dist') 3 | 4 | const { MongoClient, Db } = require('mongodb') 5 | 6 | describe('db-proxy(unit): class Accessor', () => { 7 | it('constructor() ok', () => { 8 | const client = new MongoClient('mongodb://localhost:27017/test-db') 9 | const acc = new MongoAccessor(client) 10 | assert.ok(acc.db instanceof Db) 11 | assert.ok(acc.client instanceof MongoClient) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /runtimes/nodejs/build-image.sh: -------------------------------------------------------------------------------- 1 | 2 | # Warning: just for development phase, will be move to github action in future. 3 | 4 | # get version from package.json 5 | version=$(node -p "require('./package.json').version") 6 | 7 | # build main image 8 | docker buildx build --platform linux/amd64,linux/arm64 --push -t docker.io/lafyun/runtime-node:$version -f Dockerfile . 9 | 10 | # build init image 11 | docker buildx build --platform linux/amd64,linux/arm64 --push -t docker.io/lafyun/runtime-node-init:$version -f Dockerfile.init . -------------------------------------------------------------------------------- /server/src/account/entities/account-charge-reward.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' 2 | import { ObjectId } from 'mongodb' 3 | 4 | export class AccountChargeReward { 5 | @ApiProperty({ type: String }) 6 | _id?: ObjectId 7 | 8 | @ApiProperty() 9 | amount: number 10 | 11 | @ApiProperty({}) 12 | reward: number 13 | 14 | @ApiPropertyOptional() 15 | message?: string 16 | 17 | @ApiProperty() 18 | createdAt: Date 19 | 20 | @ApiProperty() 21 | updatedAt: Date 22 | } 23 | -------------------------------------------------------------------------------- /runtimes/nodejs/src/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Collection names 3 | */ 4 | export const CLOUD_FUNCTION_COLLECTION = '__functions__' 5 | export const POLICY_COLLECTION = '__policies__' 6 | export const CONFIG_COLLECTION = '__conf__' 7 | export const WEBSITE_HOSTING_COLLECTION = '__website_hosting__' 8 | 9 | export const WEBSOCKET_FUNCTION_NAME = '__websocket__' 10 | export const INTERCEPTOR_FUNCTION_NAME = '__interceptor__' 11 | export const DEFAULT_FUNCTION_NAME = '__default__' 12 | export const INIT_FUNCTION_NAME = '__init__' 13 | -------------------------------------------------------------------------------- /server/src/i18n/en/function.json: -------------------------------------------------------------------------------- 1 | { 2 | "create": { 3 | "nameExist": "function {name} is already existed", 4 | "maxCount": "function count limit is {max}", 5 | "error": "create function error" 6 | }, 7 | "get": {}, 8 | "update": { 9 | "error": "update function error" 10 | }, 11 | "delete": { 12 | "error": "delete function error" 13 | }, 14 | "compile": { 15 | "codeRequired": "code is required" 16 | }, 17 | "common": { 18 | "notFound": "function {name} is not found" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/src/monitor/monitor.module.ts: -------------------------------------------------------------------------------- 1 | import { HttpModule } from '@nestjs/axios' 2 | import { Module } from '@nestjs/common' 3 | import { MonitorController } from './monitor.controller' 4 | import { MonitorService } from './monitor.service' 5 | import { ApplicationModule } from 'src/application/application.module' 6 | 7 | @Module({ 8 | imports: [HttpModule, ApplicationModule], 9 | controllers: [MonitorController], 10 | providers: [MonitorService], 11 | exports: [MonitorService], 12 | }) 13 | export class MonitorModule {} 14 | -------------------------------------------------------------------------------- /web/public/homepage/icon_02.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /web/src/pages/app/setting/UserSetting/CardRedemption/service.ts: -------------------------------------------------------------------------------- 1 | import { useMutation } from "@tanstack/react-query"; 2 | 3 | import { AccountControllerGiftCode } from "@/apis/v1/accounts"; 4 | 5 | export const useGiftCodeMutation = (config?: { onSuccess: (result: any) => void }) => { 6 | return useMutation( 7 | (values: any) => { 8 | return AccountControllerGiftCode(values); 9 | }, 10 | { 11 | onSuccess: async (result) => { 12 | config?.onSuccess(result); 13 | }, 14 | }, 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /e2e/9-cleaning/00-clean.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test } from '@jest/globals' 2 | import { ClearTestApplications, ClearTestUser } from '../api' 3 | import { Config } from '../config' 4 | 5 | describe('cleaning', () => { 6 | test( 7 | 'clear testing applications', 8 | async () => { 9 | await ClearTestApplications() 10 | }, 11 | 10 * 1000 12 | ) 13 | 14 | test( 15 | 'clear testing user', 16 | async () => { 17 | await ClearTestUser(Config.TEST_USERNAME) 18 | }, 19 | 10 * 1000 20 | ) 21 | }) 22 | -------------------------------------------------------------------------------- /server/src/function-template/dto/use-function-template.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString, Length } from 'class-validator' 3 | import { ObjectId } from 'mongodb' 4 | 5 | export class UseFunctionTemplateDto { 6 | @ApiProperty({ 7 | description: 'The ObjectId of function template', 8 | type: 'string', 9 | }) 10 | @IsNotEmpty() 11 | @Length(24, 24) 12 | functionTemplateId: ObjectId 13 | 14 | @ApiProperty() 15 | @IsString() 16 | @IsNotEmpty() 17 | appid: string 18 | } 19 | -------------------------------------------------------------------------------- /web/src/pages/home/mods/CreateAppModal/RuntimeItem/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { CheckIcon } from "@chakra-ui/icons"; 3 | 4 | import { TBundle } from "@/apis/typing"; 5 | 6 | export default function RuntimeItem(props: { bundle?: TBundle }) { 7 | return ( 8 |
9 | 10 | - latest 11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /server/src/authentication/entities/types.ts: -------------------------------------------------------------------------------- 1 | export enum AuthBindingType { 2 | Required = 'required', 3 | Optional = 'optional', 4 | None = 'none', 5 | } 6 | 7 | export interface AuthProviderBinding { 8 | username: AuthBindingType 9 | phone: AuthBindingType 10 | email: AuthBindingType 11 | github: AuthBindingType 12 | wechat: AuthBindingType 13 | } 14 | 15 | export interface AlismsConfig { 16 | accessKeyId: string 17 | accessKeySecret: string 18 | endpoint: string 19 | signName: string 20 | templateCode: string 21 | } 22 | -------------------------------------------------------------------------------- /server/src/initializer/deploy-manifest/databaseOpsRequestHorizontalScaling.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.kubeblocks.io/v1alpha1 2 | kind: OpsRequest 3 | metadata: 4 | labels: 5 | app.kubernetes.io/instance: <%- clusterName %> 6 | ops.kubeblocks.io/ops-type: HorizontalScaling 7 | sealos-db-provider-cr: <%- clusterName %> 8 | name: <%- name %> 9 | namespace: laf-system 10 | spec: 11 | clusterRef: <%- clusterName %> 12 | horizontalScaling: 13 | - componentName: mongodb 14 | replicas: <%- replicas %> 15 | type: HorizontalScaling 16 | -------------------------------------------------------------------------------- /server/src/authentication/dto/send-email-code.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsEmail, IsEnum, IsNotEmpty } from 'class-validator' 3 | import { EmailVerifyCodeType } from '../entities/email-verify-code' 4 | 5 | export class SendEmailCodeDto { 6 | @ApiProperty() 7 | @IsEmail() 8 | @IsNotEmpty() 9 | email: string 10 | 11 | @ApiProperty({ 12 | description: 'verify code type', 13 | enum: EmailVerifyCodeType, 14 | }) 15 | @IsNotEmpty() 16 | @IsEnum(EmailVerifyCodeType) 17 | type: EmailVerifyCodeType 18 | } 19 | -------------------------------------------------------------------------------- /server/src/log/log.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common' 2 | import { JwtService } from '@nestjs/jwt' 3 | import { DatabaseModule } from 'src/database/database.module' 4 | import { FunctionModule } from 'src/function/function.module' 5 | import { ApplicationModule } from '../application/application.module' 6 | import { LogController } from './log.controller' 7 | 8 | @Module({ 9 | imports: [ApplicationModule, FunctionModule, DatabaseModule], 10 | controllers: [LogController], 11 | providers: [JwtService], 12 | }) 13 | export class LogModule {} 14 | -------------------------------------------------------------------------------- /web/src/pages/app/functions/mods/FunctionPanel/ContextMenu/index.scss: -------------------------------------------------------------------------------- 1 | .contexify { 2 | box-shadow: none !important; 3 | border: 1px solid #e2e8f0 !important; 4 | min-width: 0 !important; 5 | justify-content: center; 6 | width: 120px; 7 | padding: 2px !important; 8 | } 9 | 10 | .contexify_theme-dark { 11 | background-color: #212630 !important; 12 | border: 1px solid rgba(255, 255, 255, 0.16) !important; 13 | } 14 | 15 | .contexify_itemContent { 16 | background: none !important; 17 | width: 100% !important; 18 | height: 100% !important; 19 | } -------------------------------------------------------------------------------- /web/src/pages/homepage/homepage.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | .homepage { 6 | -webkit-font-smoothing: auto; 7 | } 8 | 9 | @layer base { 10 | h1 { 11 | @apply text-center font-bold; 12 | } 13 | h2 { 14 | @apply text-center text-3xl font-semibold; 15 | } 16 | h3 { 17 | @apply text-3xl font-medium; 18 | } 19 | } 20 | 21 | .bg-card { 22 | background-color: #f9f9f9; 23 | } 24 | 25 | .bg-primary { 26 | background-color: #00beb1; 27 | } 28 | 29 | a:hover { 30 | opacity: 0.8; 31 | } 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | 4 | upload 5 | data/* 6 | tmp 7 | 8 | ecosystem.config.js 9 | .DS_Store 10 | .idea 11 | 12 | coverage 13 | .nyc_output 14 | 15 | kubernetes-dev/mongo-data 16 | 17 | kubernetes-local/ 18 | .vscode/configurationCache.log 19 | .vscode/dryrun.log 20 | .vscode/targets.log 21 | 22 | .kube/ 23 | 24 | build/*/manifests 25 | build/*/registry 26 | build/*/charts 27 | build/registry 28 | build-dev 29 | docs/.vitepress/.temp 30 | .idea/ 31 | 32 | update-changelog.sh 33 | runtimes/nodejs-esm 34 | yarn.lock 35 | deploy/logs/sealos.log 36 | -------------------------------------------------------------------------------- /packages/client-sdk/tests/http/read_test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | const client = require('../../dist/commonjs/index') 3 | const config = require('./config') 4 | 5 | describe('client-sdk(http): db.get()', function () { 6 | it('read empty should be ok', async () => { 7 | const cloud = client.init({ 8 | dbProxyUrl: config.dbProxyUrl, 9 | getAccessToken: config.getAccessToken, 10 | }) 11 | 12 | const res = await cloud.database().collection('categories').get() 13 | 14 | assert.ok(res.data instanceof Array) 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /server/src/region/cluster/cluster.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing' 2 | import { ClusterService } from './cluster.service' 3 | 4 | describe('ClusterService', () => { 5 | let service: ClusterService 6 | 7 | beforeEach(async () => { 8 | const module: TestingModule = await Test.createTestingModule({ 9 | providers: [ClusterService], 10 | }).compile() 11 | 12 | service = module.get(ClusterService) 13 | }) 14 | 15 | it('should be defined', () => { 16 | expect(service).toBeDefined() 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /server/src/account/dto/invite-code.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { ObjectId } from 'mongodb' 3 | 4 | export class InviteCodeProfit { 5 | @ApiProperty({ type: String }) 6 | _id: ObjectId 7 | 8 | @ApiProperty({ type: String }) 9 | uid: ObjectId 10 | 11 | @ApiProperty({ type: String }) 12 | invitedBy: ObjectId 13 | 14 | @ApiProperty({ type: String }) 15 | codeId: ObjectId 16 | 17 | @ApiProperty() 18 | createdAt: Date 19 | 20 | @ApiProperty() 21 | profit: number 22 | 23 | @ApiProperty() 24 | username: string 25 | } 26 | -------------------------------------------------------------------------------- /server/src/application/events/application-creating.event.ts: -------------------------------------------------------------------------------- 1 | import { ClientSession } from 'mongodb' 2 | import { CreateApplicationDto } from '../dto/create-application.dto' 3 | import { Region } from 'src/region/entities/region' 4 | 5 | export class ApplicationCreatingEvent { 6 | region: Region 7 | appid: string 8 | session: ClientSession 9 | dto: CreateApplicationDto 10 | 11 | constructor(partial: Partial) { 12 | Object.assign(this, partial) 13 | } 14 | 15 | static get eventName() { 16 | return 'application.creating' 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | pnpm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # OS 15 | .DS_Store 16 | 17 | # Tests 18 | /coverage 19 | /.nyc_output 20 | 21 | # IDEs and editors 22 | /.idea 23 | .project 24 | .classpath 25 | .c9/ 26 | *.launch 27 | .settings/ 28 | *.sublime-workspace 29 | 30 | # IDE - VSCode 31 | .vscode/* 32 | !.vscode/settings.json 33 | !.vscode/tasks.json 34 | !.vscode/launch.json 35 | !.vscode/extensions.json 36 | 37 | .env.local 38 | .env 39 | -------------------------------------------------------------------------------- /server/src/authentication/dto/passwd-signin.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsString, Length } from 'class-validator' 3 | 4 | export class PasswdSigninDto { 5 | @ApiProperty({ 6 | description: 'username', 7 | example: 'laf-user', 8 | }) 9 | @IsString() 10 | @IsNotEmpty() 11 | @Length(3, 64) 12 | username: string 13 | 14 | @ApiProperty({ 15 | description: 'password, 8-64 characters', 16 | example: 'laf-user-password', 17 | }) 18 | @IsString() 19 | @IsNotEmpty() 20 | @Length(8, 64) 21 | password: string 22 | } 23 | -------------------------------------------------------------------------------- /server/src/authentication/entities/email-verify-code.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | 3 | export enum EmailVerifyCodeType { 4 | Signin = 'Signin', 5 | Signup = 'Signup', 6 | ResetPassword = 'ResetPassword', 7 | Bind = 'bind', 8 | Unbind = 'Unbind', 9 | } 10 | 11 | export enum EmailVerifyCodeState { 12 | Unused = 0, 13 | Used = 1, 14 | } 15 | 16 | export class EmailVerifyCode { 17 | _id?: ObjectId 18 | email: string 19 | code: string 20 | ip: string 21 | type: EmailVerifyCodeType 22 | state: EmailVerifyCodeState 23 | createdAt: Date 24 | updatedAt: Date 25 | } 26 | -------------------------------------------------------------------------------- /server/src/website/website.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common' 2 | import { WebsiteService } from './website.service' 3 | import { WebsiteController } from './website.controller' 4 | import { ApplicationService } from 'src/application/application.service' 5 | import { StorageModule } from 'src/storage/storage.module' 6 | import { BundleService } from 'src/application/bundle.service' 7 | 8 | @Module({ 9 | imports: [StorageModule], 10 | controllers: [WebsiteController], 11 | providers: [WebsiteService, ApplicationService, BundleService], 12 | }) 13 | export class WebsiteModule {} 14 | -------------------------------------------------------------------------------- /cli/src/api/custom.ts: -------------------------------------------------------------------------------- 1 | import { request } from '../util/request' 2 | 3 | export async function databaseControllerExport(appid: string): Promise { 4 | return request({ 5 | url: `/v1/apps/${appid}/databases/export`, 6 | method: 'GET', 7 | responseType: 'stream', 8 | }) 9 | } 10 | 11 | export async function databaseControllerImport(appid: string, data: any): Promise { 12 | return request({ 13 | url: `/v1/apps/${appid}/databases/import`, 14 | method: 'PUT', 15 | data: data, 16 | headers: { 17 | 'Content-Type': 'multipart/form-data', 18 | }, 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /server/src/group/dto/get-group-invite-code-detail.dto.ts: -------------------------------------------------------------------------------- 1 | import { OmitType } from '@nestjs/mapped-types' 2 | import { GroupInviteCode } from '../entities/group-invite-code' 3 | import { Group } from '../entities/group' 4 | import { ApiProperty } from '@nestjs/swagger' 5 | import { User } from 'src/user/entities/user' 6 | 7 | export class GetGroupInviteCodeDetailDto extends OmitType(GroupInviteCode, [ 8 | 'groupId', 9 | '_id', 10 | 'createdBy', 11 | 'groupId', 12 | ]) { 13 | @ApiProperty({ type: Group }) 14 | group: Group 15 | 16 | @ApiProperty({ type: User }) 17 | invitedBy: User 18 | } 19 | -------------------------------------------------------------------------------- /server/src/initializer/deploy-manifest/databaseOpsRequestVolumeExpansion.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.kubeblocks.io/v1alpha1 2 | kind: OpsRequest 3 | metadata: 4 | labels: 5 | app.kubernetes.io/instance: <%- clusterName %> 6 | ops.kubeblocks.io/ops-type: VolumeExpansion 7 | sealos-db-provider-cr: <%- clusterName %> 8 | name: <%- name %> 9 | namespace: laf-system 10 | spec: 11 | clusterRef: <%- clusterName %> 12 | type: VolumeExpansion 13 | volumeExpansion: 14 | - componentName: mongodb 15 | volumeClaimTemplates: 16 | - name: data 17 | storage: <%- capacity %>Gi 18 | -------------------------------------------------------------------------------- /web/src/components/Panel/index.module.scss: -------------------------------------------------------------------------------- 1 | .sectionHeader { 2 | min-height: 32px; 3 | max-height: 32px; 4 | display: flex; 5 | align-items: center; 6 | 7 | h4 { 8 | padding-left: 10px; 9 | font-weight: 500; 10 | font-size: 12px; 11 | position: relative; 12 | 13 | &::before { 14 | content: " "; 15 | height: 12px; 16 | position: absolute; 17 | left: 0; 18 | top: 3px; 19 | width: 3px; 20 | background: #00a99d; 21 | border-radius: 24px; 22 | } 23 | } 24 | 25 | h4 svg { 26 | vertical-align: -4px !important; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /web/src/hooks/useDB.ts: -------------------------------------------------------------------------------- 1 | import { Cloud } from "laf-client-sdk"; 2 | 3 | import { VITE_SERVER_BASE_URL } from "../constants"; 4 | 5 | import useGlobalStore from "@/pages/globalStore"; 6 | 7 | function useDB() { 8 | const currentApp = useGlobalStore((state) => state.currentApp); 9 | const dbm_cloud = new Cloud({ 10 | baseUrl: VITE_SERVER_BASE_URL, 11 | dbProxyUrl: `/v1/apps/${currentApp?.appid}/databases/proxy`, 12 | getAccessToken: () => localStorage.getItem("token") as any, 13 | }); 14 | 15 | const db = dbm_cloud.database(); 16 | 17 | return { db }; 18 | } 19 | 20 | export default useDB; 21 | -------------------------------------------------------------------------------- /server/src/application/events/application-bundle-updating.event.ts: -------------------------------------------------------------------------------- 1 | import { ClientSession } from 'mongodb' 2 | import { Region } from 'src/region/entities/region' 3 | import { UpdateApplicationBundleDto } from '../dto/update-application.dto' 4 | 5 | export class ApplicationBundleUpdatingEvent { 6 | region: Region 7 | appid: string 8 | session: ClientSession 9 | dto: UpdateApplicationBundleDto 10 | 11 | constructor(partial: Partial) { 12 | Object.assign(this, partial) 13 | } 14 | 15 | static get eventName() { 16 | return 'application.bundle.updating' 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /web/src/components/IconText/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import clsx from "clsx"; 3 | 4 | import styles from "./index.module.scss"; 5 | 6 | export default function IconText(props: { 7 | icon: React.ReactElement; 8 | text: string; 9 | className?: string; 10 | onClick?: () => void; 11 | }) { 12 | return ( 13 |
17 | {React.cloneElement(props.icon, { 18 | height: "20px", 19 | })} 20 | {props.text} 21 |
22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /e2e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laf-testing", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "", 6 | "scripts": { 7 | "test": "jest", 8 | "lint": "eslint . --fix --ext .ts --ext .js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@jest/globals": "^29.6.2", 15 | "@types/jest": "^29.5.3", 16 | "ts-jest": "^29.1.1" 17 | }, 18 | "dependencies": { 19 | "axios": "^1.4.0", 20 | "dotenv": "^16.3.1", 21 | "mongodb": "^5.7.0" 22 | }, 23 | "lint-staged": { 24 | "*.{ts,js}": "eslint --fix" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /server/src/authentication/entities/sms-verify-code.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | 3 | export enum SmsVerifyCodeType { 4 | Signin = 'Signin', 5 | Signup = 'Signup', 6 | ResetPassword = 'ResetPassword', 7 | Bind = 'Bind', 8 | Unbind = 'Unbind', 9 | ChangePhone = 'ChangePhone', 10 | } 11 | 12 | export enum SmsVerifyCodeState { 13 | Unused = 0, 14 | Used = 1, 15 | } 16 | 17 | export class SmsVerifyCode { 18 | _id?: ObjectId 19 | phone: string 20 | code: string 21 | ip: string 22 | type: SmsVerifyCodeType 23 | state: SmsVerifyCodeState 24 | createdAt: Date 25 | updatedAt: Date 26 | } 27 | -------------------------------------------------------------------------------- /server/src/trigger/entities/cron-trigger.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | 3 | export enum TriggerState { 4 | Active = 'Active', 5 | Inactive = 'Inactive', 6 | Deleted = 'Deleted', 7 | } 8 | 9 | export enum TriggerPhase { 10 | Creating = 'Creating', 11 | Created = 'Created', 12 | Deleting = 'Deleting', 13 | Deleted = 'Deleted', 14 | } 15 | 16 | export class CronTrigger { 17 | _id?: ObjectId 18 | appid: string 19 | desc: string 20 | cron: string 21 | target: string 22 | state: TriggerState 23 | phase: TriggerPhase 24 | lockedAt: Date 25 | createdAt: Date 26 | updatedAt: Date 27 | } 28 | -------------------------------------------------------------------------------- /server/src/database/dto/create-dedicated-database.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsInt, IsNotEmpty, Max } from 'class-validator' 3 | 4 | export class CreateDedicatedDatabaseDto { 5 | @ApiProperty({ example: 200 }) 6 | @IsNotEmpty() 7 | @IsInt() 8 | cpu: number 9 | 10 | @ApiProperty({ example: 256 }) 11 | @IsNotEmpty() 12 | @IsInt() 13 | memory: number 14 | 15 | @ApiProperty({ example: 1024 }) 16 | @IsNotEmpty() 17 | @IsInt() 18 | capacity: number 19 | 20 | @ApiProperty({ example: 3 }) 21 | @IsNotEmpty() 22 | @IsInt() 23 | @Max(9) 24 | replicas: number 25 | } 26 | -------------------------------------------------------------------------------- /server/src/user/entities/pat.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | import { User } from './user' 3 | import { ApiProperty } from '@nestjs/swagger' 4 | 5 | export class PersonalAccessToken { 6 | @ApiProperty({ type: String }) 7 | _id?: ObjectId 8 | 9 | @ApiProperty({ type: String }) 10 | uid: ObjectId 11 | 12 | @ApiProperty() 13 | name: string 14 | 15 | token: string 16 | 17 | @ApiProperty() 18 | expiredAt: Date 19 | 20 | @ApiProperty() 21 | createdAt: Date 22 | } 23 | 24 | export class PersonalAccessTokenWithUser extends PersonalAccessToken { 25 | @ApiProperty({ type: User }) 26 | user: User 27 | } 28 | -------------------------------------------------------------------------------- /e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } -------------------------------------------------------------------------------- /server/src/instance/instance.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common' 2 | import { InstanceService } from './instance.service' 3 | import { InstanceTaskService } from './instance-task.service' 4 | import { StorageModule } from '../storage/storage.module' 5 | import { DatabaseModule } from '../database/database.module' 6 | import { ApplicationModule } from 'src/application/application.module' 7 | import { JwtService } from '@nestjs/jwt' 8 | 9 | @Module({ 10 | imports: [StorageModule, DatabaseModule, ApplicationModule], 11 | providers: [InstanceService, InstanceTaskService, JwtService], 12 | }) 13 | export class InstanceModule {} 14 | -------------------------------------------------------------------------------- /cli/src/common/wait.ts: -------------------------------------------------------------------------------- 1 | import { applicationControllerFindOne } from '../api/v1/application' 2 | import { AppSchema } from '../schema/app' 3 | 4 | const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay)) 5 | 6 | const interval = 2000 // interval 1000ms 7 | export async function waitApplicationState(targetState: string) { 8 | const appSchema = AppSchema.read() 9 | while (true) { 10 | const app = await applicationControllerFindOne(appSchema.appid) 11 | if (app.state === targetState) { 12 | return 13 | } 14 | sleep(interval) 15 | console.log(`application waiting ${targetState}....`) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } -------------------------------------------------------------------------------- /server/src/group/entities/group.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | import { GroupRole } from './group-member' 3 | import { ApiProperty } from '@nestjs/swagger' 4 | 5 | export class Group { 6 | @ApiProperty({ type: String }) 7 | _id?: ObjectId 8 | 9 | @ApiProperty() 10 | name: string 11 | 12 | @ApiProperty() 13 | appid?: string 14 | 15 | @ApiProperty({ type: String }) 16 | createdBy: ObjectId 17 | 18 | @ApiProperty() 19 | createdAt: Date 20 | 21 | @ApiProperty() 22 | updatedAt: Date 23 | } 24 | 25 | export class GroupWithRole extends Group { 26 | @ApiProperty({ enum: GroupRole }) 27 | role: GroupRole 28 | } 29 | -------------------------------------------------------------------------------- /server/src/application/dto/pod.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsNotEmpty, IsArray, IsString } from 'class-validator' 3 | 4 | export class PodNameListDto { 5 | @ApiProperty() 6 | appid: string 7 | 8 | @ApiProperty({ 9 | description: 'List of pod identifiers', 10 | example: ['pod1', 'pod2'], 11 | }) 12 | podNameList: string[] 13 | } 14 | 15 | export class ContainerNameListDto { 16 | @ApiProperty() 17 | podName: string 18 | 19 | @ApiProperty({ 20 | description: 'List of container identifiers', 21 | example: ['container1', 'container2'], 22 | }) 23 | containerNameList: string[] 24 | } 25 | -------------------------------------------------------------------------------- /packages/node-modules-utils/tests/cloud-sdk.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | const path = require('path') 3 | const { PackageDeclaration } = require('../dist') 4 | 5 | const nmp = path.resolve(__dirname, '../../app-service/node_modules') 6 | 7 | describe('npm-util(unit): Package Declaration Load', () => { 8 | /** 9 | * load from self package: @ 10 | */ 11 | it('load d.ts of @ (typings)', async () => { 12 | const pkg = new PackageDeclaration('@', nmp) 13 | await pkg.load() 14 | // console.log(pkg.declarations) 15 | 16 | assert.strictEqual(pkg.name, '@') 17 | assert.ok(pkg.declarations.length > 0) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /server/src/account/account.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common' 2 | import { AccountService } from './account.service' 3 | import { AccountController } from './account.controller' 4 | import { WeChatPayService } from './payment/wechat-pay.service' 5 | import { PaymentChannelService } from './payment/payment-channel.service' 6 | import { HttpModule } from '@nestjs/axios' 7 | 8 | @Module({ 9 | imports: [HttpModule], 10 | providers: [AccountService, WeChatPayService, PaymentChannelService], 11 | controllers: [AccountController], 12 | exports: [WeChatPayService, AccountService, PaymentChannelService], 13 | }) 14 | export class AccountModule {} 15 | -------------------------------------------------------------------------------- /packages/database-proxy/src/validators/index.ts: -------------------------------------------------------------------------------- 1 | import { ConditionHandler } from './condition' 2 | import { DataHandler } from './data' 3 | import { QueryHandler } from './query' 4 | import { MultiHandler } from './multi' 5 | import { JoinHandler } from './join' 6 | import { LookupHandler } from './lookup' 7 | 8 | export const condition = ConditionHandler 9 | export const cond = ConditionHandler // alias of condition 10 | 11 | export const data = DataHandler 12 | export const schema = DataHandler // alias of data 13 | export const query = QueryHandler 14 | export const multi = MultiHandler 15 | export const join = JoinHandler 16 | export const lookup = LookupHandler 17 | -------------------------------------------------------------------------------- /server/src/notification/notification.module.ts: -------------------------------------------------------------------------------- 1 | import { Global, Module } from '@nestjs/common' 2 | import { NotificationService } from './notification.service' 3 | import { NotificationTaskService } from './notification-task.service' 4 | import { NotificationController } from './notification.controller' 5 | import { HttpModule } from '@nestjs/axios' 6 | import { UserModule } from 'src/user/user.module' 7 | 8 | @Global() 9 | @Module({ 10 | providers: [NotificationService, NotificationTaskService], 11 | exports: [NotificationService], 12 | controllers: [NotificationController], 13 | imports: [HttpModule, UserModule], 14 | }) 15 | export class NotificationModule {} 16 | -------------------------------------------------------------------------------- /web/public/homepage/logo_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/database-ql/tests/units/get/orderby.test.js: -------------------------------------------------------------------------------- 1 | const { getDb } = require('../_utils') 2 | const assert = require('assert') 3 | 4 | describe('db-ql(unit): db::orderBy()', () => { 5 | it('orderBy() should be ok', async () => { 6 | const { db, req } = getDb() 7 | const res = await db 8 | .collection('tasks') 9 | .orderBy('age', 'asc') 10 | .orderBy('score', 'desc') 11 | .get() 12 | 13 | assert.ok(req.params.order.length === 2) 14 | assert.deepEqual(req.params.order[0], { field: 'age', direction: 'asc' }) 15 | assert.deepEqual(req.params.order[1], { 16 | field: 'score', 17 | direction: 'desc', 18 | }) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /packages/database-proxy/docs/ruler_v2_design.md: -------------------------------------------------------------------------------- 1 | 2 | ## 关于访问规则重新设计的讨论 3 | 4 | 1. query 重定义 5 | 2. 支持 $schema 定义 6 | 3. 将 data 验证器中对 add 和 update 操作的逻辑拆分 7 | 4. data-update 不需要 required 和 default 8 | 9 | > 重点研究 query,核心安全控制在于 query; 10 | 11 | ### data.add 12 | 13 | 1. data 中不包含任何操作符 14 | 2. 不需要 merge 选项 15 | 3. 配置为数组时,限定只允许写入数组中指定的字段 16 | 4. data.add 即 schema,考虑两者之间的关系 17 | 18 | ### data.update 19 | 20 | 1. 默认 merge == true 为 update, merge == false 时为 set(replace) 21 | 2. update 时有 $set $unset $push $inc 等操作符 22 | 3. data.update: update & set 做区分 23 | 24 | ### data.add data.update schema 25 | 26 | 1. 可考虑弱化 data.add data.update 的用法 27 | 2. schema 还是 data 的别名实现,schema 可同时作用于 udpate & add -------------------------------------------------------------------------------- /server/src/function/entities/cloud-function-history.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { ObjectId } from 'mongodb' 3 | 4 | export class CloudFunctionHistorySource { 5 | @ApiProperty() 6 | code: string 7 | } 8 | 9 | export class CloudFunctionHistory { 10 | @ApiProperty({ type: String }) 11 | _id?: ObjectId 12 | 13 | @ApiProperty() 14 | appid: string 15 | 16 | @ApiProperty({ type: String }) 17 | functionId: ObjectId 18 | 19 | @ApiProperty({ type: CloudFunctionHistorySource }) 20 | source: CloudFunctionHistorySource 21 | 22 | @ApiProperty({ type: String }) 23 | changelog?: string 24 | 25 | @ApiProperty() 26 | createdAt: Date 27 | } 28 | -------------------------------------------------------------------------------- /cli/src/api/v1/monitor.ts: -------------------------------------------------------------------------------- 1 | import { request, RequestParams } from '../../util/request' 2 | import { MonitorControllerGetDataParams } from './data-contracts' 3 | 4 | /** 5 | * No description 6 | * 7 | * @tags Monitor 8 | * @name MonitorControllerGetData 9 | * @summary Get monitor metrics data 10 | * @request GET:/v1/monitor/{appid}/metrics 11 | * @secure 12 | */ 13 | export async function monitorControllerGetData( 14 | { appid, ...query }: MonitorControllerGetDataParams, 15 | configParams: RequestParams = {}, 16 | ): Promise { 17 | return request({ 18 | url: `/v1/monitor/${appid}/metrics`, 19 | method: 'GET', 20 | params: query, 21 | ...configParams, 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /server/src/initializer/deploy-manifest/databaseOpsRequestVerticalScaling.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.kubeblocks.io/v1alpha1 2 | kind: OpsRequest 3 | metadata: 4 | labels: 5 | app.kubernetes.io/instance: <%- clusterName %> 6 | ops.kubeblocks.io/ops-type: VerticalScaling 7 | sealos-db-provider-cr: <%- clusterName %> 8 | name: <%- name %> 9 | namespace: laf-system 10 | spec: 11 | clusterRef: <%- clusterName %> 12 | type: VerticalScaling 13 | verticalScaling: 14 | - componentName: mongodb 15 | limits: 16 | cpu: <%- limitCPU %>m 17 | memory: <%- limitMemory %>Mi 18 | requests: 19 | cpu: <%- requestCPU %>m 20 | memory: <%- requestMemory %>Mi 21 | -------------------------------------------------------------------------------- /web/src/pages/app/database/CollectionDataList/mods/ColPanel/index.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from "@chakra-ui/react"; 2 | import { t } from "i18next"; 3 | 4 | import JSONEditor from "@/components/Editor/JSONEditor"; 5 | export default function ColPanel() { 6 | return ( 7 |
8 |
9 | 12 |
13 |
14 | 15 |
16 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /packages/database-ql/src/serverDate/index.ts: -------------------------------------------------------------------------------- 1 | import { SYMBOL_SERVER_DATE } from '../helper/symbol' 2 | 3 | export class ServerDate { 4 | readonly offset: number 5 | 6 | constructor({ offset = 0 } = {}) { 7 | this.offset = offset 8 | } 9 | 10 | get _internalType() { 11 | return SYMBOL_SERVER_DATE 12 | } 13 | 14 | parse() { 15 | return { 16 | $date: { 17 | offset: this.offset, 18 | }, 19 | } 20 | } 21 | } 22 | 23 | /** 24 | * @deprecated This method is deprecated, not implemented in server side 25 | * @param opt 26 | * @returns 27 | */ 28 | export function ServerDateConstructor(opt?: { offset: number }) { 29 | return new ServerDate(opt) 30 | } 31 | -------------------------------------------------------------------------------- /server/src/storage/dto/create-bucket.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsEnum, IsNotEmpty, Matches } from 'class-validator' 3 | import { BucketPolicy } from '../entities/storage-bucket' 4 | 5 | export class CreateBucketDto { 6 | @ApiProperty({ 7 | description: 'The short name of the bucket which not contain the appid', 8 | }) 9 | @IsNotEmpty() 10 | @Matches(/^[a-z0-9][a-z0-9-]{1,30}[a-z0-9]$/) 11 | shortName: string 12 | 13 | @ApiProperty({ 14 | enum: BucketPolicy, 15 | }) 16 | @IsEnum(BucketPolicy) 17 | @IsNotEmpty() 18 | policy: BucketPolicy 19 | 20 | fullname(appid: string) { 21 | return `${appid}-${this.shortName}` 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /services/runtime-exporter/src/logger.ts: -------------------------------------------------------------------------------- 1 | import { LoggerInterface } from 'database-proxy' 2 | import * as log4js from 'log4js' 3 | import Config from './config' 4 | 5 | /** 6 | * Create logger instance 7 | * @param category log category 8 | * @param level the logger level : 'fatal', 'error', 'warning', 'info', 'debug', 'trace' 9 | * @returns 10 | */ 11 | export function createLogger( 12 | category: string, 13 | level?: string, 14 | ): LoggerInterface { 15 | const logger = log4js.getLogger(category) 16 | logger.level = level ?? Config.LOG_LEVEL 17 | 18 | return logger as any 19 | } 20 | 21 | /** 22 | * The global logger instance 23 | */ 24 | export const logger = createLogger('server') 25 | -------------------------------------------------------------------------------- /web/src/apis/dependence.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | interface KeyWord { 3 | q: String; 4 | } 5 | 6 | export async function DependencySearch(params: KeyWord | any): Promise { 7 | if (params.q === "") { 8 | return Promise.resolve([]); 9 | } else { 10 | return axios.get(`https://registry.npmjs.org/-/v1/search`, { 11 | params: { 12 | text: params.q, 13 | size: 4, 14 | }, 15 | }); 16 | } 17 | } 18 | 19 | export async function GetDependencyVersions(params: KeyWord | any): Promise { 20 | if (params.q === "") { 21 | return Promise.resolve([]); 22 | } else { 23 | return axios.get(`https://registry.npmjs.org/${params.q}`); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /web/src/pages/homepage/circle.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | type Props = {}; 4 | 5 | const circle = (props: Props) => { 6 | return ( 7 |
8 |
9 |
10 |
11 |
12 |
13 | ); 14 | }; 15 | 16 | export default circle; 17 | -------------------------------------------------------------------------------- /server/src/website/entities/website.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from 'mongodb' 2 | import { DomainPhase, DomainState } from 'src/gateway/entities/runtime-domain' 3 | import { StorageBucket } from 'src/storage/entities/storage-bucket' 4 | 5 | export class WebsiteHosting { 6 | _id?: ObjectId 7 | appid: string 8 | bucketName: string 9 | domain: string 10 | isCustom: boolean 11 | state: DomainState 12 | phase: DomainPhase 13 | createdAt: Date 14 | updatedAt: Date 15 | lockedAt: Date 16 | 17 | constructor(partial: Partial) { 18 | Object.assign(this, partial) 19 | } 20 | } 21 | 22 | export type WebsiteHostingWithBucket = WebsiteHosting & { 23 | bucket: StorageBucket 24 | } 25 | -------------------------------------------------------------------------------- /server/src/authentication/dto/send-phone-code.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger' 2 | import { IsEnum, IsNotEmpty, IsString, Matches } from 'class-validator' 3 | import { SmsVerifyCodeType } from '../entities/sms-verify-code' 4 | 5 | export class SendPhoneCodeDto { 6 | @ApiProperty({ 7 | description: 'phone', 8 | example: '13805718888', 9 | }) 10 | @IsString() 11 | @IsNotEmpty() 12 | @Matches(/^1[3-9]\d{9}$/) 13 | phone: string 14 | 15 | @ApiProperty({ 16 | description: 'verify code type', 17 | example: 'Signin | Signup | ResetPassword | Bind | Unbind | ChangePhone', 18 | }) 19 | @IsNotEmpty() 20 | @IsEnum(SmsVerifyCodeType) 21 | type: SmsVerifyCodeType 22 | } 23 | -------------------------------------------------------------------------------- /server/src/group/entities/group-invite-code.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' 2 | import { ObjectId } from 'mongodb' 3 | import { GroupRole } from './group-member' 4 | 5 | export class GroupInviteCode { 6 | @ApiProperty({ type: 'string' }) 7 | _id?: ObjectId 8 | 9 | @ApiPropertyOptional({ type: 'string' }) 10 | usedBy?: ObjectId 11 | 12 | @ApiProperty() 13 | code: string 14 | 15 | @ApiProperty() 16 | role: GroupRole 17 | 18 | @ApiProperty({ type: 'string' }) 19 | groupId: ObjectId 20 | 21 | @ApiProperty({ type: 'string' }) 22 | createdBy: ObjectId 23 | 24 | @ApiProperty() 25 | createdAt: Date 26 | 27 | @ApiProperty() 28 | updatedAt: Date 29 | } 30 | -------------------------------------------------------------------------------- /server/src/user/entities/user.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' 2 | import { ObjectId } from 'mongodb' 3 | import { UserProfile } from './user-profile' 4 | 5 | export class User { 6 | @ApiProperty({ type: String }) 7 | _id?: ObjectId 8 | 9 | @ApiProperty() 10 | username: string 11 | 12 | @ApiPropertyOptional() 13 | email?: string 14 | 15 | @ApiPropertyOptional() 16 | phone?: string 17 | 18 | @ApiPropertyOptional() 19 | github?: number 20 | 21 | @ApiProperty() 22 | createdAt: Date 23 | 24 | @ApiProperty() 25 | updatedAt: Date 26 | } 27 | 28 | export class UserWithProfile extends User { 29 | @ApiPropertyOptional() 30 | profile?: UserProfile 31 | } 32 | -------------------------------------------------------------------------------- /web/src/hooks/useCustomToast.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useToast } from "@chakra-ui/react"; 3 | 4 | function useCustomToast() { 5 | const toast = useToast(); 6 | 7 | const showSuccess = (text: string | React.ReactNode) => { 8 | toast({ 9 | position: "top", 10 | title: text, 11 | status: "success", 12 | duration: 1000, 13 | }); 14 | }; 15 | 16 | const showError = (text: string | React.ReactNode) => { 17 | toast({ 18 | position: "top", 19 | title: text, 20 | status: "error", 21 | duration: 1000, 22 | }); 23 | }; 24 | return { 25 | showSuccess, 26 | showError, 27 | }; 28 | } 29 | 30 | export default useCustomToast; 31 | -------------------------------------------------------------------------------- /cli/src/command/application/index.ts: -------------------------------------------------------------------------------- 1 | import { Command, program } from 'commander' 2 | import { init, list } from '../../action/application' 3 | 4 | export function command(): Command { 5 | const cmd = program.command('app') 6 | 7 | cmd 8 | .command('init ') 9 | .description('initialize application') 10 | .option('-s, --sync', 'sync application data', false) 11 | .option('-b --basic-mode', 'only create .app.yaml, do not init whole project', false) 12 | .action((appid, options) => { 13 | init(appid, options) 14 | }) 15 | 16 | cmd 17 | .command('list') 18 | .description('list application') 19 | .action(() => { 20 | list() 21 | }) 22 | 23 | return cmd 24 | } 25 | -------------------------------------------------------------------------------- /cli/src/command/environment/index.ts: -------------------------------------------------------------------------------- 1 | import { Command, program } from 'commander' 2 | import { checkApplication } from '../../common/hook' 3 | import { pull, push } from '../../action/environment' 4 | 5 | export function command(): Command { 6 | const cmd = program 7 | .command('environment') 8 | .alias('env') 9 | .hook('preAction', () => { 10 | checkApplication() 11 | }) 12 | 13 | cmd 14 | .command('pull') 15 | .description('pull environment variables') 16 | .action(() => { 17 | pull() 18 | }) 19 | 20 | cmd 21 | .command('push') 22 | .description('push environment variables') 23 | .action(() => { 24 | push() 25 | }) 26 | 27 | return cmd 28 | } 29 | -------------------------------------------------------------------------------- /web/src/pages/app/setting/SysSetting/AppEnvList/EditTextarea/index.tsx: -------------------------------------------------------------------------------- 1 | import { Textarea } from "@chakra-ui/react"; 2 | import { t } from "i18next"; 3 | 4 | const EditTextarea = function (props: { 5 | text: string; 6 | value: number; 7 | onChange: (data: any) => any; 8 | onBlur: (data: any) => any; 9 | disabled: boolean; 10 | }) { 11 | const { text, value, onBlur, onChange, disabled } = props; 12 | return ( 13 |