From 06b8c68fa6e9dd34a9c8bd18502c61c767218b61 Mon Sep 17 00:00:00 2001 From: marcus-sa <8391194+marcus-sa@users.noreply.github.com> Date: Fri, 9 Aug 2024 21:31:52 +0200 Subject: [PATCH] save --- .editorconfig | 13 +++ .env | 11 ++ .eslintignore | 1 + .eslintrc.json | 42 +++++++ .github/workflows/ci.yml | 39 +++++++ .gitignore | 42 +++++++ .prettierignore | 5 + .prettierrc | 7 ++ .tool-versions | 2 + .vscode/extensions.json | 7 ++ README.md | 76 +++++++++++++ accounting-service-api/.eslintrc.json | 30 +++++ accounting-service-api/README.md | 11 ++ accounting-service-api/package.json | 10 ++ accounting-service-api/project.json | 26 +++++ accounting-service-api/src/index.ts | 1 + .../src/lib/order-service-api.spec.ts | 7 ++ .../src/lib/order-service-api.ts | 3 + accounting-service-api/tsconfig.json | 13 +++ accounting-service-api/tsconfig.lib.json | 10 ++ accounting-service-api/tsconfig.spec.json | 26 +++++ accounting-service-api/vite.config.ts | 27 +++++ accounting-service/.eslintrc.json | 18 +++ accounting-service/project.json | 104 ++++++++++++++++++ accounting-service/src/assets/.gitkeep | 0 accounting-service/src/main.ts | 1 + accounting-service/tsconfig.app.json | 9 ++ accounting-service/tsconfig.json | 17 +++ accounting-service/tsconfig.spec.json | 8 ++ accounting-service/vite.config.ts | 6 + api-gateway/.eslintrc.json | 18 +++ api-gateway/project.json | 104 ++++++++++++++++++ api-gateway/src/assets/.gitkeep | 0 api-gateway/src/main.ts | 1 + api-gateway/tsconfig.app.json | 9 ++ api-gateway/tsconfig.json | 17 +++ api-gateway/tsconfig.spec.json | 8 ++ api-gateway/vite.config.ts | 6 + bun.lockb | Bin 0 -> 375008 bytes consumer-service-api/.eslintrc.json | 30 +++++ consumer-service-api/README.md | 11 ++ consumer-service-api/package.json | 10 ++ consumer-service-api/project.json | 26 +++++ consumer-service-api/src/index.ts | 2 + .../src/lib/entities/consumer.ts | 14 +++ .../src/lib/entities/index.ts | 1 + consumer-service-api/src/lib/service.ts | 10 ++ consumer-service-api/tsconfig.json | 13 +++ consumer-service-api/tsconfig.lib.json | 10 ++ consumer-service-api/tsconfig.spec.json | 26 +++++ consumer-service-api/vite.config.ts | 27 +++++ consumer-service/.env | 2 + consumer-service/.eslintrc.json | 18 +++ consumer-service/project.json | 104 ++++++++++++++++++ consumer-service/src/assets/.gitkeep | 0 consumer-service/src/config.ts | 9 ++ consumer-service/src/consumer.controller.ts | 0 consumer-service/src/consumer.repository.ts | 4 + consumer-service/src/consumer.service.ts | 18 +++ consumer-service/src/main.ts | 19 ++++ consumer-service/tsconfig.app.json | 9 ++ consumer-service/tsconfig.json | 17 +++ consumer-service/tsconfig.spec.json | 8 ++ consumer-service/vite.config.ts | 6 + delivery-service-api/.eslintrc.json | 30 +++++ delivery-service-api/README.md | 11 ++ delivery-service-api/package.json | 10 ++ delivery-service-api/project.json | 26 +++++ delivery-service-api/src/index.ts | 1 + .../src/lib/order-service-api.spec.ts | 7 ++ .../src/lib/order-service-api.ts | 3 + delivery-service-api/tsconfig.json | 13 +++ delivery-service-api/tsconfig.lib.json | 10 ++ delivery-service-api/tsconfig.spec.json | 26 +++++ delivery-service-api/vite.config.ts | 27 +++++ delivery-service/.eslintrc.json | 18 +++ delivery-service/project.json | 104 ++++++++++++++++++ delivery-service/src/assets/.gitkeep | 0 delivery-service/src/main.ts | 1 + delivery-service/tsconfig.app.json | 9 ++ delivery-service/tsconfig.json | 17 +++ delivery-service/tsconfig.spec.json | 8 ++ delivery-service/vite.config.ts | 6 + docker-compose.yml | 24 ++++ infra/postgres/deploy.sh | 0 infra/restate/Kraftfile | 0 infra/restate/deploy.sh | 0 infra/restate/project.json | 0 infra/restate/restate.toml | 3 + kitchen-service-api/.eslintrc.json | 30 +++++ kitchen-service-api/README.md | 11 ++ kitchen-service-api/package.json | 10 ++ kitchen-service-api/project.json | 26 +++++ kitchen-service-api/src/index.ts | 1 + .../src/lib/order-service-api.spec.ts | 7 ++ .../src/lib/order-service-api.ts | 3 + kitchen-service-api/tsconfig.json | 13 +++ kitchen-service-api/tsconfig.lib.json | 10 ++ kitchen-service-api/tsconfig.spec.json | 26 +++++ kitchen-service-api/vite.config.ts | 27 +++++ kitchen-service/.eslintrc.json | 18 +++ kitchen-service/project.json | 104 ++++++++++++++++++ kitchen-service/src/assets/.gitkeep | 0 kitchen-service/src/main.ts | 1 + kitchen-service/tsconfig.app.json | 9 ++ kitchen-service/tsconfig.json | 17 +++ kitchen-service/tsconfig.spec.json | 8 ++ kitchen-service/vite.config.ts | 6 + node-vite-config.ts | 75 +++++++++++++ nx.json | 49 +++++++++ order-history-service/.eslintrc.json | 18 +++ order-history-service/project.json | 104 ++++++++++++++++++ order-history-service/src/assets/.gitkeep | 0 order-history-service/src/main.ts | 1 + order-history-service/tsconfig.app.json | 9 ++ order-history-service/tsconfig.json | 17 +++ order-history-service/tsconfig.spec.json | 8 ++ order-history-service/vite.config.ts | 6 + order-service-api/.eslintrc.json | 30 +++++ order-service-api/README.md | 11 ++ order-service-api/package.json | 10 ++ order-service-api/project.json | 26 +++++ order-service-api/src/index.ts | 1 + .../src/lib/order-service-api.spec.ts | 7 ++ .../src/lib/order-service-api.ts | 3 + order-service-api/tsconfig.json | 13 +++ order-service-api/tsconfig.lib.json | 10 ++ order-service-api/tsconfig.spec.json | 26 +++++ order-service-api/vite.config.ts | 27 +++++ order-service/.eslintrc.json | 18 +++ order-service/project.json | 104 ++++++++++++++++++ order-service/src/assets/.gitkeep | 0 order-service/src/main.ts | 1 + order-service/tsconfig.app.json | 9 ++ order-service/tsconfig.json | 17 +++ order-service/tsconfig.spec.json | 8 ++ order-service/vite.config.ts | 6 + package.json | 57 ++++++++++ patches/typescript@5.5.4.patch | 13 +++ restaurant-service-api/.eslintrc.json | 30 +++++ restaurant-service-api/README.md | 11 ++ restaurant-service-api/package.json | 10 ++ restaurant-service-api/project.json | 26 +++++ restaurant-service-api/src/index.ts | 1 + .../src/lib/order-service-api.spec.ts | 7 ++ .../src/lib/order-service-api.ts | 3 + restaurant-service-api/tsconfig.json | 13 +++ restaurant-service-api/tsconfig.lib.json | 10 ++ restaurant-service-api/tsconfig.spec.json | 26 +++++ restaurant-service-api/vite.config.ts | 27 +++++ restaurant-service/.eslintrc.json | 18 +++ restaurant-service/project.json | 104 ++++++++++++++++++ restaurant-service/src/assets/.gitkeep | 0 restaurant-service/src/main.ts | 1 + restaurant-service/tsconfig.app.json | 9 ++ restaurant-service/tsconfig.json | 17 +++ restaurant-service/tsconfig.spec.json | 8 ++ restaurant-service/vite.config.ts | 6 + shared/.eslintrc.json | 30 +++++ shared/README.md | 11 ++ shared/package.json | 10 ++ shared/project.json | 26 +++++ shared/src/index.ts | 3 + shared/src/lib/config.ts | 16 +++ shared/src/lib/repository.ts | 36 ++++++ shared/src/lib/types.ts | 4 + shared/tsconfig.json | 13 +++ shared/tsconfig.lib.json | 10 ++ shared/tsconfig.spec.json | 26 +++++ shared/vite.config.ts | 27 +++++ tsconfig.base.json | 55 +++++++++ vitest.workspace.ts | 1 + 172 files changed, 3089 insertions(+) create mode 100644 .editorconfig create mode 100644 .env create mode 100644 .eslintignore create mode 100644 .eslintrc.json create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 .tool-versions create mode 100644 .vscode/extensions.json create mode 100644 README.md create mode 100644 accounting-service-api/.eslintrc.json create mode 100644 accounting-service-api/README.md create mode 100644 accounting-service-api/package.json create mode 100644 accounting-service-api/project.json create mode 100644 accounting-service-api/src/index.ts create mode 100644 accounting-service-api/src/lib/order-service-api.spec.ts create mode 100644 accounting-service-api/src/lib/order-service-api.ts create mode 100644 accounting-service-api/tsconfig.json create mode 100644 accounting-service-api/tsconfig.lib.json create mode 100644 accounting-service-api/tsconfig.spec.json create mode 100644 accounting-service-api/vite.config.ts create mode 100644 accounting-service/.eslintrc.json create mode 100644 accounting-service/project.json create mode 100644 accounting-service/src/assets/.gitkeep create mode 100644 accounting-service/src/main.ts create mode 100644 accounting-service/tsconfig.app.json create mode 100644 accounting-service/tsconfig.json create mode 100644 accounting-service/tsconfig.spec.json create mode 100644 accounting-service/vite.config.ts create mode 100644 api-gateway/.eslintrc.json create mode 100644 api-gateway/project.json create mode 100644 api-gateway/src/assets/.gitkeep create mode 100644 api-gateway/src/main.ts create mode 100644 api-gateway/tsconfig.app.json create mode 100644 api-gateway/tsconfig.json create mode 100644 api-gateway/tsconfig.spec.json create mode 100644 api-gateway/vite.config.ts create mode 100755 bun.lockb create mode 100644 consumer-service-api/.eslintrc.json create mode 100644 consumer-service-api/README.md create mode 100644 consumer-service-api/package.json create mode 100644 consumer-service-api/project.json create mode 100644 consumer-service-api/src/index.ts create mode 100644 consumer-service-api/src/lib/entities/consumer.ts create mode 100644 consumer-service-api/src/lib/entities/index.ts create mode 100644 consumer-service-api/src/lib/service.ts create mode 100644 consumer-service-api/tsconfig.json create mode 100644 consumer-service-api/tsconfig.lib.json create mode 100644 consumer-service-api/tsconfig.spec.json create mode 100644 consumer-service-api/vite.config.ts create mode 100644 consumer-service/.env create mode 100644 consumer-service/.eslintrc.json create mode 100644 consumer-service/project.json create mode 100644 consumer-service/src/assets/.gitkeep create mode 100644 consumer-service/src/config.ts create mode 100644 consumer-service/src/consumer.controller.ts create mode 100644 consumer-service/src/consumer.repository.ts create mode 100644 consumer-service/src/consumer.service.ts create mode 100644 consumer-service/src/main.ts create mode 100644 consumer-service/tsconfig.app.json create mode 100644 consumer-service/tsconfig.json create mode 100644 consumer-service/tsconfig.spec.json create mode 100644 consumer-service/vite.config.ts create mode 100644 delivery-service-api/.eslintrc.json create mode 100644 delivery-service-api/README.md create mode 100644 delivery-service-api/package.json create mode 100644 delivery-service-api/project.json create mode 100644 delivery-service-api/src/index.ts create mode 100644 delivery-service-api/src/lib/order-service-api.spec.ts create mode 100644 delivery-service-api/src/lib/order-service-api.ts create mode 100644 delivery-service-api/tsconfig.json create mode 100644 delivery-service-api/tsconfig.lib.json create mode 100644 delivery-service-api/tsconfig.spec.json create mode 100644 delivery-service-api/vite.config.ts create mode 100644 delivery-service/.eslintrc.json create mode 100644 delivery-service/project.json create mode 100644 delivery-service/src/assets/.gitkeep create mode 100644 delivery-service/src/main.ts create mode 100644 delivery-service/tsconfig.app.json create mode 100644 delivery-service/tsconfig.json create mode 100644 delivery-service/tsconfig.spec.json create mode 100644 delivery-service/vite.config.ts create mode 100644 docker-compose.yml create mode 100644 infra/postgres/deploy.sh create mode 100644 infra/restate/Kraftfile create mode 100644 infra/restate/deploy.sh create mode 100644 infra/restate/project.json create mode 100644 infra/restate/restate.toml create mode 100644 kitchen-service-api/.eslintrc.json create mode 100644 kitchen-service-api/README.md create mode 100644 kitchen-service-api/package.json create mode 100644 kitchen-service-api/project.json create mode 100644 kitchen-service-api/src/index.ts create mode 100644 kitchen-service-api/src/lib/order-service-api.spec.ts create mode 100644 kitchen-service-api/src/lib/order-service-api.ts create mode 100644 kitchen-service-api/tsconfig.json create mode 100644 kitchen-service-api/tsconfig.lib.json create mode 100644 kitchen-service-api/tsconfig.spec.json create mode 100644 kitchen-service-api/vite.config.ts create mode 100644 kitchen-service/.eslintrc.json create mode 100644 kitchen-service/project.json create mode 100644 kitchen-service/src/assets/.gitkeep create mode 100644 kitchen-service/src/main.ts create mode 100644 kitchen-service/tsconfig.app.json create mode 100644 kitchen-service/tsconfig.json create mode 100644 kitchen-service/tsconfig.spec.json create mode 100644 kitchen-service/vite.config.ts create mode 100644 node-vite-config.ts create mode 100644 nx.json create mode 100644 order-history-service/.eslintrc.json create mode 100644 order-history-service/project.json create mode 100644 order-history-service/src/assets/.gitkeep create mode 100644 order-history-service/src/main.ts create mode 100644 order-history-service/tsconfig.app.json create mode 100644 order-history-service/tsconfig.json create mode 100644 order-history-service/tsconfig.spec.json create mode 100644 order-history-service/vite.config.ts create mode 100644 order-service-api/.eslintrc.json create mode 100644 order-service-api/README.md create mode 100644 order-service-api/package.json create mode 100644 order-service-api/project.json create mode 100644 order-service-api/src/index.ts create mode 100644 order-service-api/src/lib/order-service-api.spec.ts create mode 100644 order-service-api/src/lib/order-service-api.ts create mode 100644 order-service-api/tsconfig.json create mode 100644 order-service-api/tsconfig.lib.json create mode 100644 order-service-api/tsconfig.spec.json create mode 100644 order-service-api/vite.config.ts create mode 100644 order-service/.eslintrc.json create mode 100644 order-service/project.json create mode 100644 order-service/src/assets/.gitkeep create mode 100644 order-service/src/main.ts create mode 100644 order-service/tsconfig.app.json create mode 100644 order-service/tsconfig.json create mode 100644 order-service/tsconfig.spec.json create mode 100644 order-service/vite.config.ts create mode 100644 package.json create mode 100644 patches/typescript@5.5.4.patch create mode 100644 restaurant-service-api/.eslintrc.json create mode 100644 restaurant-service-api/README.md create mode 100644 restaurant-service-api/package.json create mode 100644 restaurant-service-api/project.json create mode 100644 restaurant-service-api/src/index.ts create mode 100644 restaurant-service-api/src/lib/order-service-api.spec.ts create mode 100644 restaurant-service-api/src/lib/order-service-api.ts create mode 100644 restaurant-service-api/tsconfig.json create mode 100644 restaurant-service-api/tsconfig.lib.json create mode 100644 restaurant-service-api/tsconfig.spec.json create mode 100644 restaurant-service-api/vite.config.ts create mode 100644 restaurant-service/.eslintrc.json create mode 100644 restaurant-service/project.json create mode 100644 restaurant-service/src/assets/.gitkeep create mode 100644 restaurant-service/src/main.ts create mode 100644 restaurant-service/tsconfig.app.json create mode 100644 restaurant-service/tsconfig.json create mode 100644 restaurant-service/tsconfig.spec.json create mode 100644 restaurant-service/vite.config.ts create mode 100644 shared/.eslintrc.json create mode 100644 shared/README.md create mode 100644 shared/package.json create mode 100644 shared/project.json create mode 100644 shared/src/index.ts create mode 100644 shared/src/lib/config.ts create mode 100644 shared/src/lib/repository.ts create mode 100644 shared/src/lib/types.ts create mode 100644 shared/tsconfig.json create mode 100644 shared/tsconfig.lib.json create mode 100644 shared/tsconfig.spec.json create mode 100644 shared/vite.config.ts create mode 100644 tsconfig.base.json create mode 100644 vitest.workspace.ts diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6e87a00 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.env b/.env new file mode 100644 index 0000000..a00d6d5 --- /dev/null +++ b/.env @@ -0,0 +1,11 @@ +# Postgres +DATABASE_HOST=localhost +DATABASE_NAME=ftgo +DATABASE_USER=ftgo +DATABASE_PASSWORD=ftgo +DATABASE_PORT=5432 + +# Restate +RESTATE_HOST=localhost +RESTATE_ADMIN_PORT=9070 +RESTATE_INGRESS_PORT=8080 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +node_modules diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..0be733b --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,42 @@ +{ + "root": true, + "ignorePatterns": ["**/*"], + "plugins": ["@nx"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": { + "@nx/enforce-module-boundaries": [ + "error", + { + "enforceBuildableLibDependency": true, + "allow": [], + "depConstraints": [ + { + "sourceTag": "*", + "onlyDependOnLibsWithTags": ["*"] + } + ] + } + ] + } + }, + { + "files": ["*.ts", "*.tsx"], + "extends": ["plugin:@nx/typescript"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "extends": ["plugin:@nx/javascript"], + "rules": {} + }, + { + "files": ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"], + "env": { + "jest": true + }, + "rules": {} + } + ] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..12d2dd5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,39 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + +permissions: + actions: read + contents: read + +jobs: + main: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + + - uses: oven-sh/setup-bun@v1 + with: + bun-version: latest + + + # This enables task distribution via Nx Cloud + # Run this command as early as possible, before dependencies are installed + # Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun + - run: bunx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build" + + + - run: bun install --no-cache + - uses: nrwl/nx-set-shas@v4 + + # Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud + # - run: bun nx-cloud record -- echo Hello World + # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected + - run: bun nx affected -t lint test build diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4f4d87b --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +dist +tmp +/out-tsc + +# dependencies +node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db + +.nx/cache +.nx/workspace-data diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..e26f0b3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +# Add files here to ignore them from prettier formatting +/dist +/coverage +/.nx/cache +/.nx/workspace-data \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..1968d4f --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "trailingComma": "all", + "bracketSpacing": true, + "tabWidth": 2, + "singleQuote": true, + "arrowParens": "avoid" +} diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..ba4598a --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +bun 1.1.22 +nodejs 22.6.0 diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..97e81d4 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "nrwl.angular-console", + "esbenp.prettier-vscode", + "firsttris.vscode-jest-runner" + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..187776f --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +# DeepkitFtgoExample + + + +✨ **This workspace has been generated by [Nx, Smart Monorepos · Fast CI.](https://nx.dev)** ✨ + +## Integrate with editors + +Enhance your Nx experience by installing [Nx Console](https://nx.dev/nx-console) for your favorite editor. Nx Console +provides an interactive UI to view your projects, run tasks, generate code, and more! Available for VSCode, IntelliJ and +comes with a LSP for Vim users. + +## Nx plugins and code generators + +Add Nx plugins to leverage their code generators and automated, inferred tasks. + +``` +# Add plugin +npx nx add @nx/react + +# Use code generator +npx nx generate @nx/react:app demo + +# Run development server +npx nx serve demo + +# View project details +npx nx show project demo --web +``` + +Run `npx nx list` to get a list of available plugins and whether they have generators. Then run `npx nx list ` to see what generators are available. + +Learn more about [code generators](https://nx.dev/features/generate-code) and [inferred tasks](https://nx.dev/concepts/inferred-tasks) in the docs. + +## Running tasks + +To execute tasks with Nx use the following syntax: + +``` +npx nx <...options> +``` + +You can also run multiple targets: + +``` +npx nx run-many -t +``` + +..or add `-p` to filter specific projects + +``` +npx nx run-many -t -p +``` + +Targets can be defined in the `package.json` or `projects.json`. Learn more [in the docs](https://nx.dev/features/run-tasks). + +## Set up CI! + +Nx comes with local caching already built-in (check your `nx.json`). On CI you might want to go a step further. + +- [Set up remote caching](https://nx.dev/features/share-your-cache) +- [Set up task distribution across multiple machines](https://nx.dev/nx-cloud/features/distribute-task-execution) +- [Learn more how to setup CI](https://nx.dev/recipes/ci) + +## Explore the project graph + +Run `npx nx graph` to show the graph of the workspace. +It will show tasks that you can run with Nx. + +- [Learn more about Exploring the Project Graph](https://nx.dev/core-features/explore-graph) + +## Connect with us! + +- [Join the community](https://nx.dev/community) +- [Subscribe to the Nx Youtube Channel](https://www.youtube.com/@nxdevtools) +- [Follow us on Twitter](https://twitter.com/nxdevtools) diff --git a/accounting-service-api/.eslintrc.json b/accounting-service-api/.eslintrc.json new file mode 100644 index 0000000..4069f0d --- /dev/null +++ b/accounting-service-api/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/vite.config.{js,ts,mjs,mts}"] + } + ] + } + } + ] +} diff --git a/accounting-service-api/README.md b/accounting-service-api/README.md new file mode 100644 index 0000000..1f26b18 --- /dev/null +++ b/accounting-service-api/README.md @@ -0,0 +1,11 @@ +# accounting-service-api + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build accounting-service-api` to build the library. + +## Running unit tests + +Run `nx test accounting-service-api` to execute the unit tests via [Vitest](https://vitest.dev/). diff --git a/accounting-service-api/package.json b/accounting-service-api/package.json new file mode 100644 index 0000000..1683b9f --- /dev/null +++ b/accounting-service-api/package.json @@ -0,0 +1,10 @@ +{ + "name": "@ftgo/accounting-service-api", + "version": "0.0.1", + "dependencies": { + "tslib": "^2.3.0" + }, + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "private": true +} diff --git a/accounting-service-api/project.json b/accounting-service-api/project.json new file mode 100644 index 0000000..7ba573f --- /dev/null +++ b/accounting-service-api/project.json @@ -0,0 +1,26 @@ +{ + "name": "accounting-service-api", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "accounting-service-api/src", + "projectType": "library", + "tags": [], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/accounting-service-api", + "main": "accounting-service-api/src/index.ts", + "tsConfig": "accounting-service-api/tsconfig.lib.json", + "assets": ["accounting-service-api/*.md"] + } + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "reportsDirectory": "../coverage/accounting-service-api" + } + } + } +} diff --git a/accounting-service-api/src/index.ts b/accounting-service-api/src/index.ts new file mode 100644 index 0000000..29fd230 --- /dev/null +++ b/accounting-service-api/src/index.ts @@ -0,0 +1 @@ +export * from './lib/accounting-service-api'; diff --git a/accounting-service-api/src/lib/order-service-api.spec.ts b/accounting-service-api/src/lib/order-service-api.spec.ts new file mode 100644 index 0000000..c09df56 --- /dev/null +++ b/accounting-service-api/src/lib/order-service-api.spec.ts @@ -0,0 +1,7 @@ +import { orderServiceApi } from './accounting-service-api'; + +describe('orderServiceApi', () => { + it('should work', () => { + expect(orderServiceApi()).toEqual('accounting-service-api'); + }); +}); diff --git a/accounting-service-api/src/lib/order-service-api.ts b/accounting-service-api/src/lib/order-service-api.ts new file mode 100644 index 0000000..e07c024 --- /dev/null +++ b/accounting-service-api/src/lib/order-service-api.ts @@ -0,0 +1,3 @@ +export function orderServiceApi(): string { + return 'accounting-service-api'; +} diff --git a/accounting-service-api/tsconfig.json b/accounting-service-api/tsconfig.json new file mode 100644 index 0000000..e236e0f --- /dev/null +++ b/accounting-service-api/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/accounting-service-api/tsconfig.lib.json b/accounting-service-api/tsconfig.lib.json new file mode 100644 index 0000000..2fd1e3f --- /dev/null +++ b/accounting-service-api/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/accounting-service-api/tsconfig.spec.json b/accounting-service-api/tsconfig.spec.json new file mode 100644 index 0000000..4f7fed6 --- /dev/null +++ b/accounting-service-api/tsconfig.spec.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "vitest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/accounting-service-api/vite.config.ts b/accounting-service-api/vite.config.ts new file mode 100644 index 0000000..ff00450 --- /dev/null +++ b/accounting-service-api/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite'; + +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; + +export default defineConfig({ + root: __dirname, + cacheDir: '../node_modules/.vite/accounting-service-api', + + plugins: [nxViteTsPaths()], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + test: { + watch: false, + globals: true, + environment: 'node', + include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + coverage: { + reportsDirectory: '../coverage/accounting-service-api', + provider: 'v8', + }, + }, +}); diff --git a/accounting-service/.eslintrc.json b/accounting-service/.eslintrc.json new file mode 100644 index 0000000..1ad7cf0 --- /dev/null +++ b/accounting-service/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/accounting-service/project.json b/accounting-service/project.json new file mode 100644 index 0000000..cdd5eec --- /dev/null +++ b/accounting-service/project.json @@ -0,0 +1,104 @@ +{ + "name": "accounting-service", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "ftgo", + "sourceRoot": "accounting-service/src", + "tags": [], + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "development", + "inputs": ["accounting-service"], + "options": { + "buildLibsFromSource": false, + "generatePackageJson": true, + "outputPath": "dist/accounting-service", + "ssr": "src/main.ts", + "emptyOutDir": true, + "outputFileName": "main.mjs" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "accounting-service:build", + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "accounting-service:build:development", + "args": ["accounting-service:start"], + "watch": true + }, + "production": { + "buildTarget": "accounting-service:build:production" + }, + "staging": { + "buildTarget": "accounting-service:build:staging" + } + } + }, + "container": { + "executor": "@nx-tools/nx-container:build", + "dependsOn": ["build"], + "options": { + "engine": "docker", + "push": true, + "cache-from": ["type=gha"], + "cache-to": ["type=gha,mode=max"], + "metadata": { + "images": ["ghcr.io/zapxme/accounting-service"], + "tags": [ + "type=schedule", + "type=ref,event=branch", + "type=ref,event=tag", + "type=ref,event=pr", + "type=sha,prefix=sha-" + ] + } + } + }, + "create-migration": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "accounting-service:build", + "args": [ + "migration:create", + "--migrationDir", + "accounting-service/src/migrations" + ], + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "accounting-service:build:development" + }, + "production": { + "buildTarget": "accounting-service:build:production" + }, + "staging": { + "buildTarget": "accounting-service:build:staging" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{projectRoot}/coverage"] + } + } +} diff --git a/accounting-service/src/assets/.gitkeep b/accounting-service/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/accounting-service/src/main.ts b/accounting-service/src/main.ts new file mode 100644 index 0000000..3451e9b --- /dev/null +++ b/accounting-service/src/main.ts @@ -0,0 +1 @@ +console.log('Hello World'); diff --git a/accounting-service/tsconfig.app.json b/accounting-service/tsconfig.app.json new file mode 100644 index 0000000..aa1b0e5 --- /dev/null +++ b/accounting-service/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/accounting-service/tsconfig.json b/accounting-service/tsconfig.json new file mode 100644 index 0000000..60bce4b --- /dev/null +++ b/accounting-service/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "strictPropertyInitialization": false, + "types": ["vite/client"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/accounting-service/tsconfig.spec.json b/accounting-service/tsconfig.spec.json new file mode 100644 index 0000000..bd57cb3 --- /dev/null +++ b/accounting-service/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts"] +} diff --git a/accounting-service/vite.config.ts b/accounting-service/vite.config.ts new file mode 100644 index 0000000..876a12c --- /dev/null +++ b/accounting-service/vite.config.ts @@ -0,0 +1,6 @@ +// eslint-disable-next-line @nx/enforce-module-boundaries +import { defineNodeConfig } from '../node-vite-config'; + +export default defineNodeConfig({ + root: __dirname, +}); diff --git a/api-gateway/.eslintrc.json b/api-gateway/.eslintrc.json new file mode 100644 index 0000000..1ad7cf0 --- /dev/null +++ b/api-gateway/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/api-gateway/project.json b/api-gateway/project.json new file mode 100644 index 0000000..c484484 --- /dev/null +++ b/api-gateway/project.json @@ -0,0 +1,104 @@ +{ + "name": "api-gateway", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "ftgo", + "sourceRoot": "api-gateway/src", + "tags": [], + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "development", + "inputs": ["api-gateway"], + "options": { + "buildLibsFromSource": false, + "generatePackageJson": true, + "outputPath": "dist/api-gateway", + "ssr": "src/main.ts", + "emptyOutDir": true, + "outputFileName": "main.mjs" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "api-gateway:build", + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "api-gateway:build:development", + "args": ["api-gateway:start"], + "watch": true + }, + "production": { + "buildTarget": "api-gateway:build:production" + }, + "staging": { + "buildTarget": "api-gateway:build:staging" + } + } + }, + "container": { + "executor": "@nx-tools/nx-container:build", + "dependsOn": ["build"], + "options": { + "engine": "docker", + "push": true, + "cache-from": ["type=gha"], + "cache-to": ["type=gha,mode=max"], + "metadata": { + "images": ["ghcr.io/zapxme/api-gateway"], + "tags": [ + "type=schedule", + "type=ref,event=branch", + "type=ref,event=tag", + "type=ref,event=pr", + "type=sha,prefix=sha-" + ] + } + } + }, + "create-migration": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "api-gateway:build", + "args": [ + "migration:create", + "--migrationDir", + "api-gateway/src/migrations" + ], + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "api-gateway:build:development" + }, + "production": { + "buildTarget": "api-gateway:build:production" + }, + "staging": { + "buildTarget": "api-gateway:build:staging" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{projectRoot}/coverage"] + } + } +} diff --git a/api-gateway/src/assets/.gitkeep b/api-gateway/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/api-gateway/src/main.ts b/api-gateway/src/main.ts new file mode 100644 index 0000000..3451e9b --- /dev/null +++ b/api-gateway/src/main.ts @@ -0,0 +1 @@ +console.log('Hello World'); diff --git a/api-gateway/tsconfig.app.json b/api-gateway/tsconfig.app.json new file mode 100644 index 0000000..aa1b0e5 --- /dev/null +++ b/api-gateway/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/api-gateway/tsconfig.json b/api-gateway/tsconfig.json new file mode 100644 index 0000000..60bce4b --- /dev/null +++ b/api-gateway/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "strictPropertyInitialization": false, + "types": ["vite/client"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/api-gateway/tsconfig.spec.json b/api-gateway/tsconfig.spec.json new file mode 100644 index 0000000..bd57cb3 --- /dev/null +++ b/api-gateway/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts"] +} diff --git a/api-gateway/vite.config.ts b/api-gateway/vite.config.ts new file mode 100644 index 0000000..876a12c --- /dev/null +++ b/api-gateway/vite.config.ts @@ -0,0 +1,6 @@ +// eslint-disable-next-line @nx/enforce-module-boundaries +import { defineNodeConfig } from '../node-vite-config'; + +export default defineNodeConfig({ + root: __dirname, +}); diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..0653049dac1cd13c16f0fdaaa35c639fabc92bc2 GIT binary patch literal 375008 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 { + return Object.assign(new Consumer(), data); + } +} + diff --git a/consumer-service-api/src/lib/entities/index.ts b/consumer-service-api/src/lib/entities/index.ts new file mode 100644 index 0000000..fd46f68 --- /dev/null +++ b/consumer-service-api/src/lib/entities/index.ts @@ -0,0 +1 @@ +export * from './consumer'; diff --git a/consumer-service-api/src/lib/service.ts b/consumer-service-api/src/lib/service.ts new file mode 100644 index 0000000..39efffd --- /dev/null +++ b/consumer-service-api/src/lib/service.ts @@ -0,0 +1,10 @@ +import {RestateService} from "deepkit-restate"; +import {UUID} from "@deepkit/type"; + +import {PersonName} from "@ftgo/shared"; + +export interface ConsumerServiceHandlers { + create(name: PersonName): Promise; +} + +export type ConsumerServiceApi = RestateService<'consumer', ConsumerServiceHandlers>; diff --git a/consumer-service-api/tsconfig.json b/consumer-service-api/tsconfig.json new file mode 100644 index 0000000..e236e0f --- /dev/null +++ b/consumer-service-api/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/consumer-service-api/tsconfig.lib.json b/consumer-service-api/tsconfig.lib.json new file mode 100644 index 0000000..2fd1e3f --- /dev/null +++ b/consumer-service-api/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/consumer-service-api/tsconfig.spec.json b/consumer-service-api/tsconfig.spec.json new file mode 100644 index 0000000..4f7fed6 --- /dev/null +++ b/consumer-service-api/tsconfig.spec.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "vitest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/consumer-service-api/vite.config.ts b/consumer-service-api/vite.config.ts new file mode 100644 index 0000000..8d2b25e --- /dev/null +++ b/consumer-service-api/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite'; + +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; + +export default defineConfig({ + root: __dirname, + cacheDir: '../node_modules/.vite/consumer-service-api', + + plugins: [nxViteTsPaths()], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + test: { + watch: false, + globals: true, + environment: 'node', + include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + coverage: { + reportsDirectory: '../coverage/consumer-service-api', + provider: 'v8', + }, + }, +}); diff --git a/consumer-service/.env b/consumer-service/.env new file mode 100644 index 0000000..e7d90c4 --- /dev/null +++ b/consumer-service/.env @@ -0,0 +1,2 @@ +# Restate +RESTATE_PORT=9080 diff --git a/consumer-service/.eslintrc.json b/consumer-service/.eslintrc.json new file mode 100644 index 0000000..1ad7cf0 --- /dev/null +++ b/consumer-service/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/consumer-service/project.json b/consumer-service/project.json new file mode 100644 index 0000000..145bf77 --- /dev/null +++ b/consumer-service/project.json @@ -0,0 +1,104 @@ +{ + "name": "consumer-service", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "ftgo", + "sourceRoot": "consumer-service/src", + "tags": [], + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "development", + "inputs": ["consumer-service"], + "options": { + "buildLibsFromSource": false, + "generatePackageJson": true, + "outputPath": "dist/consumer-service", + "ssr": "src/main.ts", + "emptyOutDir": true, + "outputFileName": "main.mjs" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "consumer-service:build", + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "consumer-service:build:development", + "args": ["consumer-service:start"], + "watch": true + }, + "production": { + "buildTarget": "consumer-service:build:production" + }, + "staging": { + "buildTarget": "consumer-service:build:staging" + } + } + }, + "container": { + "executor": "@nx-tools/nx-container:build", + "dependsOn": ["build"], + "options": { + "engine": "docker", + "push": true, + "cache-from": ["type=gha"], + "cache-to": ["type=gha,mode=max"], + "metadata": { + "images": ["ghcr.io/zapxme/consumer-service"], + "tags": [ + "type=schedule", + "type=ref,event=branch", + "type=ref,event=tag", + "type=ref,event=pr", + "type=sha,prefix=sha-" + ] + } + } + }, + "create-migration": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "consumer-service:build", + "args": [ + "migration:create", + "--migrationDir", + "consumer-service/src/migrations" + ], + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "consumer-service:build:development" + }, + "production": { + "buildTarget": "consumer-service:build:production" + }, + "staging": { + "buildTarget": "consumer-service:build:staging" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{projectRoot}/coverage"] + } + } +} diff --git a/consumer-service/src/assets/.gitkeep b/consumer-service/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/consumer-service/src/config.ts b/consumer-service/src/config.ts new file mode 100644 index 0000000..d66f826 --- /dev/null +++ b/consumer-service/src/config.ts @@ -0,0 +1,9 @@ +import { FrameworkConfig } from '@deepkit/framework'; + +import { DatabaseConfig, RestateConfig } from '@ftgo/shared'; + +export class ConsumerServiceConfig { + readonly database: DatabaseConfig; + readonly restate: RestateConfig; + readonly framework?: FrameworkConfig; +} diff --git a/consumer-service/src/consumer.controller.ts b/consumer-service/src/consumer.controller.ts new file mode 100644 index 0000000..e69de29 diff --git a/consumer-service/src/consumer.repository.ts b/consumer-service/src/consumer.repository.ts new file mode 100644 index 0000000..0f50c72 --- /dev/null +++ b/consumer-service/src/consumer.repository.ts @@ -0,0 +1,4 @@ +import { Repository } from '@ftgo/shared'; +import { Consumer } from '@ftgo/consumer-service-api'; + +export class ConsumerRepository extends Repository(Consumer) {} diff --git a/consumer-service/src/consumer.service.ts b/consumer-service/src/consumer.service.ts new file mode 100644 index 0000000..8cd48a3 --- /dev/null +++ b/consumer-service/src/consumer.service.ts @@ -0,0 +1,18 @@ +import {restate, RestateServiceContext} from "deepkit-restate"; +import {Consumer, ConsumerServiceApi, ConsumerServiceHandlers} from "@ftgo/consumer-service-api"; +import {PersonName} from "@ftgo/shared"; +import {UUID} from "@deepkit/type"; + +import {ConsumerRepository} from "./consumer.repository"; + +@restate.service() +export class ConsumerService implements ConsumerServiceHandlers { + constructor( + private readonly ctx: RestateServiceContext, + private readonly consumerRepository: ConsumerRepository, + ) {} + + async create(name: PersonName): Promise { + const consumer = await this.ctx.run(() => this.consumerRepository.create({ name })); + } +} diff --git a/consumer-service/src/main.ts b/consumer-service/src/main.ts new file mode 100644 index 0000000..8d2dad1 --- /dev/null +++ b/consumer-service/src/main.ts @@ -0,0 +1,19 @@ +import {App} from '@deepkit/app'; +import {FrameworkModule} from '@deepkit/framework'; +import {RestateModule} from 'deepkit-restate'; + +import {ConsumerServiceConfig} from './config'; + +void new App({ + config: ConsumerServiceConfig, + imports: [new FrameworkModule(), new RestateModule()], +}) + .setup((module, config: ConsumerServiceConfig) => { + module + .getImportedModuleByClass(FrameworkModule) + .configure(config.framework); + + module.getImportedModuleByClass(RestateModule).configure(config.restate); + }) + .loadConfigFromEnv({ prefix: '' }) + .run(); diff --git a/consumer-service/tsconfig.app.json b/consumer-service/tsconfig.app.json new file mode 100644 index 0000000..aa1b0e5 --- /dev/null +++ b/consumer-service/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/consumer-service/tsconfig.json b/consumer-service/tsconfig.json new file mode 100644 index 0000000..60bce4b --- /dev/null +++ b/consumer-service/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "strictPropertyInitialization": false, + "types": ["vite/client"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/consumer-service/tsconfig.spec.json b/consumer-service/tsconfig.spec.json new file mode 100644 index 0000000..bd57cb3 --- /dev/null +++ b/consumer-service/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts"] +} diff --git a/consumer-service/vite.config.ts b/consumer-service/vite.config.ts new file mode 100644 index 0000000..876a12c --- /dev/null +++ b/consumer-service/vite.config.ts @@ -0,0 +1,6 @@ +// eslint-disable-next-line @nx/enforce-module-boundaries +import { defineNodeConfig } from '../node-vite-config'; + +export default defineNodeConfig({ + root: __dirname, +}); diff --git a/delivery-service-api/.eslintrc.json b/delivery-service-api/.eslintrc.json new file mode 100644 index 0000000..4069f0d --- /dev/null +++ b/delivery-service-api/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/vite.config.{js,ts,mjs,mts}"] + } + ] + } + } + ] +} diff --git a/delivery-service-api/README.md b/delivery-service-api/README.md new file mode 100644 index 0000000..2c0c908 --- /dev/null +++ b/delivery-service-api/README.md @@ -0,0 +1,11 @@ +# delivery-service-api + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build delivery-service-api` to build the library. + +## Running unit tests + +Run `nx test delivery-service-api` to execute the unit tests via [Vitest](https://vitest.dev/). diff --git a/delivery-service-api/package.json b/delivery-service-api/package.json new file mode 100644 index 0000000..9c81c74 --- /dev/null +++ b/delivery-service-api/package.json @@ -0,0 +1,10 @@ +{ + "name": "@ftgo/delivery-service-api", + "version": "0.0.1", + "dependencies": { + "tslib": "^2.3.0" + }, + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "private": true +} diff --git a/delivery-service-api/project.json b/delivery-service-api/project.json new file mode 100644 index 0000000..574bb0d --- /dev/null +++ b/delivery-service-api/project.json @@ -0,0 +1,26 @@ +{ + "name": "delivery-service-api", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "delivery-service-api/src", + "projectType": "library", + "tags": [], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/delivery-service-api", + "main": "delivery-service-api/src/index.ts", + "tsConfig": "delivery-service-api/tsconfig.lib.json", + "assets": ["delivery-service-api/*.md"] + } + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "reportsDirectory": "../coverage/delivery-service-api" + } + } + } +} diff --git a/delivery-service-api/src/index.ts b/delivery-service-api/src/index.ts new file mode 100644 index 0000000..04d3503 --- /dev/null +++ b/delivery-service-api/src/index.ts @@ -0,0 +1 @@ +export * from './lib/delivery-service-api'; diff --git a/delivery-service-api/src/lib/order-service-api.spec.ts b/delivery-service-api/src/lib/order-service-api.spec.ts new file mode 100644 index 0000000..32f4899 --- /dev/null +++ b/delivery-service-api/src/lib/order-service-api.spec.ts @@ -0,0 +1,7 @@ +import { orderServiceApi } from './delivery-service-api'; + +describe('orderServiceApi', () => { + it('should work', () => { + expect(orderServiceApi()).toEqual('delivery-service-api'); + }); +}); diff --git a/delivery-service-api/src/lib/order-service-api.ts b/delivery-service-api/src/lib/order-service-api.ts new file mode 100644 index 0000000..23aec2f --- /dev/null +++ b/delivery-service-api/src/lib/order-service-api.ts @@ -0,0 +1,3 @@ +export function orderServiceApi(): string { + return 'delivery-service-api'; +} diff --git a/delivery-service-api/tsconfig.json b/delivery-service-api/tsconfig.json new file mode 100644 index 0000000..e236e0f --- /dev/null +++ b/delivery-service-api/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/delivery-service-api/tsconfig.lib.json b/delivery-service-api/tsconfig.lib.json new file mode 100644 index 0000000..2fd1e3f --- /dev/null +++ b/delivery-service-api/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/delivery-service-api/tsconfig.spec.json b/delivery-service-api/tsconfig.spec.json new file mode 100644 index 0000000..4f7fed6 --- /dev/null +++ b/delivery-service-api/tsconfig.spec.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "vitest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/delivery-service-api/vite.config.ts b/delivery-service-api/vite.config.ts new file mode 100644 index 0000000..bad338a --- /dev/null +++ b/delivery-service-api/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite'; + +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; + +export default defineConfig({ + root: __dirname, + cacheDir: '../node_modules/.vite/delivery-service-api', + + plugins: [nxViteTsPaths()], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + test: { + watch: false, + globals: true, + environment: 'node', + include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + coverage: { + reportsDirectory: '../coverage/delivery-service-api', + provider: 'v8', + }, + }, +}); diff --git a/delivery-service/.eslintrc.json b/delivery-service/.eslintrc.json new file mode 100644 index 0000000..1ad7cf0 --- /dev/null +++ b/delivery-service/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/delivery-service/project.json b/delivery-service/project.json new file mode 100644 index 0000000..18c4353 --- /dev/null +++ b/delivery-service/project.json @@ -0,0 +1,104 @@ +{ + "name": "delivery-service", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "ftgo", + "sourceRoot": "delivery-service/src", + "tags": [], + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "development", + "inputs": ["delivery-service"], + "options": { + "buildLibsFromSource": false, + "generatePackageJson": true, + "outputPath": "dist/delivery-service", + "ssr": "src/main.ts", + "emptyOutDir": true, + "outputFileName": "main.mjs" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "delivery-service:build", + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "delivery-service:build:development", + "args": ["delivery-service:start"], + "watch": true + }, + "production": { + "buildTarget": "delivery-service:build:production" + }, + "staging": { + "buildTarget": "delivery-service:build:staging" + } + } + }, + "container": { + "executor": "@nx-tools/nx-container:build", + "dependsOn": ["build"], + "options": { + "engine": "docker", + "push": true, + "cache-from": ["type=gha"], + "cache-to": ["type=gha,mode=max"], + "metadata": { + "images": ["ghcr.io/zapxme/delivery-service"], + "tags": [ + "type=schedule", + "type=ref,event=branch", + "type=ref,event=tag", + "type=ref,event=pr", + "type=sha,prefix=sha-" + ] + } + } + }, + "create-migration": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "delivery-service:build", + "args": [ + "migration:create", + "--migrationDir", + "delivery-service/src/migrations" + ], + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "delivery-service:build:development" + }, + "production": { + "buildTarget": "delivery-service:build:production" + }, + "staging": { + "buildTarget": "delivery-service:build:staging" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{projectRoot}/coverage"] + } + } +} diff --git a/delivery-service/src/assets/.gitkeep b/delivery-service/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/delivery-service/src/main.ts b/delivery-service/src/main.ts new file mode 100644 index 0000000..3451e9b --- /dev/null +++ b/delivery-service/src/main.ts @@ -0,0 +1 @@ +console.log('Hello World'); diff --git a/delivery-service/tsconfig.app.json b/delivery-service/tsconfig.app.json new file mode 100644 index 0000000..aa1b0e5 --- /dev/null +++ b/delivery-service/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/delivery-service/tsconfig.json b/delivery-service/tsconfig.json new file mode 100644 index 0000000..60bce4b --- /dev/null +++ b/delivery-service/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "strictPropertyInitialization": false, + "types": ["vite/client"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/delivery-service/tsconfig.spec.json b/delivery-service/tsconfig.spec.json new file mode 100644 index 0000000..bd57cb3 --- /dev/null +++ b/delivery-service/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts"] +} diff --git a/delivery-service/vite.config.ts b/delivery-service/vite.config.ts new file mode 100644 index 0000000..876a12c --- /dev/null +++ b/delivery-service/vite.config.ts @@ -0,0 +1,6 @@ +// eslint-disable-next-line @nx/enforce-module-boundaries +import { defineNodeConfig } from '../node-vite-config'; + +export default defineNodeConfig({ + root: __dirname, +}); diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c05ddcb --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,24 @@ +services: + postgres: + image: docker.io/postgres:16.4-alpine3.19 + ports: + - '${DATABASE_PORT}:5432' + environment: + - 'POSTGRES_DATABASE=${DATABASE_NAME}' + - 'POSTGRES_USER=${DATABASE_USER}' + - 'POSTGRES_PASSWORD=${DATABASE_PASSWORD}' + volumes: + - ./scripts/postgres:/docker-entrypoint-initdb.d + - postgres:/var/lib/postgresql/data + + restate: + image: docker.io/restatedev/restate:1.0 + ports: + - '${RESTATE_INGRESS_PORT}:8080' + - '${RESTATE_ADMIN_PORT}:9070' + environment: + - 'RESTATE_CONFIG=/etc/config/restate.toml' + volumes: + - ./infra/restate/restate.toml:/etc/config/restate.toml + extra_hosts: + - 'host.docker.internal:host-gateway' diff --git a/infra/postgres/deploy.sh b/infra/postgres/deploy.sh new file mode 100644 index 0000000..e69de29 diff --git a/infra/restate/Kraftfile b/infra/restate/Kraftfile new file mode 100644 index 0000000..e69de29 diff --git a/infra/restate/deploy.sh b/infra/restate/deploy.sh new file mode 100644 index 0000000..e69de29 diff --git a/infra/restate/project.json b/infra/restate/project.json new file mode 100644 index 0000000..e69de29 diff --git a/infra/restate/restate.toml b/infra/restate/restate.toml new file mode 100644 index 0000000..b878298 --- /dev/null +++ b/infra/restate/restate.toml @@ -0,0 +1,3 @@ +[worker.invoker.retry-policy] +initial-interval = "50ms" +max-attempts = 3 diff --git a/kitchen-service-api/.eslintrc.json b/kitchen-service-api/.eslintrc.json new file mode 100644 index 0000000..4069f0d --- /dev/null +++ b/kitchen-service-api/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/vite.config.{js,ts,mjs,mts}"] + } + ] + } + } + ] +} diff --git a/kitchen-service-api/README.md b/kitchen-service-api/README.md new file mode 100644 index 0000000..7bcb739 --- /dev/null +++ b/kitchen-service-api/README.md @@ -0,0 +1,11 @@ +# kitchen-service-api + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build kitchen-service-api` to build the library. + +## Running unit tests + +Run `nx test kitchen-service-api` to execute the unit tests via [Vitest](https://vitest.dev/). diff --git a/kitchen-service-api/package.json b/kitchen-service-api/package.json new file mode 100644 index 0000000..1f144a1 --- /dev/null +++ b/kitchen-service-api/package.json @@ -0,0 +1,10 @@ +{ + "name": "@ftgo/kitchen-service-api", + "version": "0.0.1", + "dependencies": { + "tslib": "^2.3.0" + }, + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "private": true +} diff --git a/kitchen-service-api/project.json b/kitchen-service-api/project.json new file mode 100644 index 0000000..7d5b794 --- /dev/null +++ b/kitchen-service-api/project.json @@ -0,0 +1,26 @@ +{ + "name": "kitchen-service-api", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "kitchen-service-api/src", + "projectType": "library", + "tags": [], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/kitchen-service-api", + "main": "kitchen-service-api/src/index.ts", + "tsConfig": "kitchen-service-api/tsconfig.lib.json", + "assets": ["kitchen-service-api/*.md"] + } + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "reportsDirectory": "../coverage/kitchen-service-api" + } + } + } +} diff --git a/kitchen-service-api/src/index.ts b/kitchen-service-api/src/index.ts new file mode 100644 index 0000000..8513732 --- /dev/null +++ b/kitchen-service-api/src/index.ts @@ -0,0 +1 @@ +export * from './lib/kitchen-service-api'; diff --git a/kitchen-service-api/src/lib/order-service-api.spec.ts b/kitchen-service-api/src/lib/order-service-api.spec.ts new file mode 100644 index 0000000..6338a94 --- /dev/null +++ b/kitchen-service-api/src/lib/order-service-api.spec.ts @@ -0,0 +1,7 @@ +import { orderServiceApi } from './kitchen-service-api'; + +describe('orderServiceApi', () => { + it('should work', () => { + expect(orderServiceApi()).toEqual('kitchen-service-api'); + }); +}); diff --git a/kitchen-service-api/src/lib/order-service-api.ts b/kitchen-service-api/src/lib/order-service-api.ts new file mode 100644 index 0000000..24332a4 --- /dev/null +++ b/kitchen-service-api/src/lib/order-service-api.ts @@ -0,0 +1,3 @@ +export function orderServiceApi(): string { + return 'kitchen-service-api'; +} diff --git a/kitchen-service-api/tsconfig.json b/kitchen-service-api/tsconfig.json new file mode 100644 index 0000000..e236e0f --- /dev/null +++ b/kitchen-service-api/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/kitchen-service-api/tsconfig.lib.json b/kitchen-service-api/tsconfig.lib.json new file mode 100644 index 0000000..2fd1e3f --- /dev/null +++ b/kitchen-service-api/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/kitchen-service-api/tsconfig.spec.json b/kitchen-service-api/tsconfig.spec.json new file mode 100644 index 0000000..4f7fed6 --- /dev/null +++ b/kitchen-service-api/tsconfig.spec.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "vitest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/kitchen-service-api/vite.config.ts b/kitchen-service-api/vite.config.ts new file mode 100644 index 0000000..51c976c --- /dev/null +++ b/kitchen-service-api/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite'; + +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; + +export default defineConfig({ + root: __dirname, + cacheDir: '../node_modules/.vite/kitchen-service-api', + + plugins: [nxViteTsPaths()], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + test: { + watch: false, + globals: true, + environment: 'node', + include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + coverage: { + reportsDirectory: '../coverage/kitchen-service-api', + provider: 'v8', + }, + }, +}); diff --git a/kitchen-service/.eslintrc.json b/kitchen-service/.eslintrc.json new file mode 100644 index 0000000..1ad7cf0 --- /dev/null +++ b/kitchen-service/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/kitchen-service/project.json b/kitchen-service/project.json new file mode 100644 index 0000000..1f4b2b1 --- /dev/null +++ b/kitchen-service/project.json @@ -0,0 +1,104 @@ +{ + "name": "kitchen-service", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "ftgo", + "sourceRoot": "kitchen-service/src", + "tags": [], + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "development", + "inputs": ["kitchen-service"], + "options": { + "buildLibsFromSource": false, + "generatePackageJson": true, + "outputPath": "dist/kitchen-service", + "ssr": "src/main.ts", + "emptyOutDir": true, + "outputFileName": "main.mjs" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "kitchen-service:build", + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "kitchen-service:build:development", + "args": ["kitchen-service:start"], + "watch": true + }, + "production": { + "buildTarget": "kitchen-service:build:production" + }, + "staging": { + "buildTarget": "kitchen-service:build:staging" + } + } + }, + "container": { + "executor": "@nx-tools/nx-container:build", + "dependsOn": ["build"], + "options": { + "engine": "docker", + "push": true, + "cache-from": ["type=gha"], + "cache-to": ["type=gha,mode=max"], + "metadata": { + "images": ["ghcr.io/zapxme/kitchen-service"], + "tags": [ + "type=schedule", + "type=ref,event=branch", + "type=ref,event=tag", + "type=ref,event=pr", + "type=sha,prefix=sha-" + ] + } + } + }, + "create-migration": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "kitchen-service:build", + "args": [ + "migration:create", + "--migrationDir", + "kitchen-service/src/migrations" + ], + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "kitchen-service:build:development" + }, + "production": { + "buildTarget": "kitchen-service:build:production" + }, + "staging": { + "buildTarget": "kitchen-service:build:staging" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{projectRoot}/coverage"] + } + } +} diff --git a/kitchen-service/src/assets/.gitkeep b/kitchen-service/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/kitchen-service/src/main.ts b/kitchen-service/src/main.ts new file mode 100644 index 0000000..3451e9b --- /dev/null +++ b/kitchen-service/src/main.ts @@ -0,0 +1 @@ +console.log('Hello World'); diff --git a/kitchen-service/tsconfig.app.json b/kitchen-service/tsconfig.app.json new file mode 100644 index 0000000..aa1b0e5 --- /dev/null +++ b/kitchen-service/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/kitchen-service/tsconfig.json b/kitchen-service/tsconfig.json new file mode 100644 index 0000000..60bce4b --- /dev/null +++ b/kitchen-service/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "strictPropertyInitialization": false, + "types": ["vite/client"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/kitchen-service/tsconfig.spec.json b/kitchen-service/tsconfig.spec.json new file mode 100644 index 0000000..bd57cb3 --- /dev/null +++ b/kitchen-service/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts"] +} diff --git a/kitchen-service/vite.config.ts b/kitchen-service/vite.config.ts new file mode 100644 index 0000000..876a12c --- /dev/null +++ b/kitchen-service/vite.config.ts @@ -0,0 +1,6 @@ +// eslint-disable-next-line @nx/enforce-module-boundaries +import { defineNodeConfig } from '../node-vite-config'; + +export default defineNodeConfig({ + root: __dirname, +}); diff --git a/node-vite-config.ts b/node-vite-config.ts new file mode 100644 index 0000000..45ec0ab --- /dev/null +++ b/node-vite-config.ts @@ -0,0 +1,75 @@ +import { deepkitType } from '@deepkit/vite'; +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; +import { join } from 'node:path'; +import { workspaceRoot } from '@nx/devkit'; +import { defineConfig, PluginOption } from 'vite'; + +export interface NodeViteConfigOptions { + readonly root: string; + readonly plugins?: readonly PluginOption[]; + readonly debug?: boolean; +} + +export function defineNodeConfig({ + root, + plugins, + debug, +}: NodeViteConfigOptions) { + return defineConfig(({ mode }) => { + const tsConfig = + mode === 'test' + ? join(root, 'tsconfig.spec.json') + : join(root, 'tsconfig.app.json'); + + const projectPathFromWorkspaceRoot = root.replace(`${workspaceRoot}/`, ''); + + return { + root, + build: { + minify: mode === 'production', + rollupOptions: { + preserveEntrySignatures: 'strict', + output: { + esModule: true, + entryFileNames: `[name].mjs`, + }, + }, + }, + resolve: { + mainFields: ['module'], + }, + plugins: [ + deepkitType({ + tsConfig, + compilerOptions: { + sourceMap: true, + }, + }), + nxViteTsPaths({ debug }), + ...(plugins || []), + ], + test: { + globals: true, + passWithNoTests: true, + environment: 'node', + include: ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default', 'hanging-process'], + coverage: { + reportsDirectory: join( + workspaceRoot, + 'coverage', + projectPathFromWorkspaceRoot, + ), + provider: 'v8', + }, + cache: { + dir: join(workspaceRoot, 'node_modules/.cache/vitest'), + }, + }, + define: { + 'import.meta.vitest': mode === 'test', + 'import.meta.env.NX_WORKSPACE_ROOT': JSON.stringify(workspaceRoot), + }, + }; + }); +} diff --git a/nx.json b/nx.json new file mode 100644 index 0000000..a7e483c --- /dev/null +++ b/nx.json @@ -0,0 +1,49 @@ +{ + "$schema": "./node_modules/nx/schemas/nx-schema.json", + "namedInputs": { + "default": ["{projectRoot}/**/*", "sharedGlobals"], + "production": [ + "default", + "!{projectRoot}/.eslintrc.json", + "!{projectRoot}/eslint.config.js", + "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)", + "!{projectRoot}/tsconfig.spec.json", + "!{projectRoot}/jest.config.[jt]s", + "!{projectRoot}/src/test-setup.[jt]s", + "!{projectRoot}/test-setup.[jt]s" + ], + "sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"] + }, + "nxCloudAccessToken": "Y2NmZjM5N2ItMzA2Ny00OTc4LWI5NTUtMzU2MGFlZGI3NDk0fHJlYWQtd3JpdGU=", + "targetDefaults": { + "@nx/esbuild:esbuild": { + "cache": true, + "dependsOn": ["^build"], + "inputs": ["production", "^production"] + }, + "@nx/js:tsc": { + "cache": true, + "dependsOn": ["^build"], + "inputs": ["production", "^production"] + }, + "@nx/vite:test": { + "cache": true, + "inputs": ["default", "^production"] + } + }, + "plugins": [ + { + "plugin": "@nx/eslint/plugin", + "options": { + "targetName": "lint" + } + }, + { + "plugin": "@nx/jest/plugin", + "options": { + "targetName": "test" + }, + "exclude": ["order-service-e2e/**/*"] + } + ] +} diff --git a/order-history-service/.eslintrc.json b/order-history-service/.eslintrc.json new file mode 100644 index 0000000..1ad7cf0 --- /dev/null +++ b/order-history-service/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/order-history-service/project.json b/order-history-service/project.json new file mode 100644 index 0000000..39ee7bb --- /dev/null +++ b/order-history-service/project.json @@ -0,0 +1,104 @@ +{ + "name": "order-history-service", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "ftgo", + "sourceRoot": "order-history-service/src", + "tags": [], + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "development", + "inputs": ["order-history-service"], + "options": { + "buildLibsFromSource": false, + "generatePackageJson": true, + "outputPath": "dist/order-history-service", + "ssr": "src/main.ts", + "emptyOutDir": true, + "outputFileName": "main.mjs" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "order-history-service:build", + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "order-history-service:build:development", + "args": ["order-history-service:start"], + "watch": true + }, + "production": { + "buildTarget": "order-history-service:build:production" + }, + "staging": { + "buildTarget": "order-history-service:build:staging" + } + } + }, + "container": { + "executor": "@nx-tools/nx-container:build", + "dependsOn": ["build"], + "options": { + "engine": "docker", + "push": true, + "cache-from": ["type=gha"], + "cache-to": ["type=gha,mode=max"], + "metadata": { + "images": ["ghcr.io/zapxme/order-history-service"], + "tags": [ + "type=schedule", + "type=ref,event=branch", + "type=ref,event=tag", + "type=ref,event=pr", + "type=sha,prefix=sha-" + ] + } + } + }, + "create-migration": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "order-history-service:build", + "args": [ + "migration:create", + "--migrationDir", + "order-history-service/src/migrations" + ], + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "order-history-service:build:development" + }, + "production": { + "buildTarget": "order-history-service:build:production" + }, + "staging": { + "buildTarget": "order-history-service:build:staging" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{projectRoot}/coverage"] + } + } +} diff --git a/order-history-service/src/assets/.gitkeep b/order-history-service/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/order-history-service/src/main.ts b/order-history-service/src/main.ts new file mode 100644 index 0000000..3451e9b --- /dev/null +++ b/order-history-service/src/main.ts @@ -0,0 +1 @@ +console.log('Hello World'); diff --git a/order-history-service/tsconfig.app.json b/order-history-service/tsconfig.app.json new file mode 100644 index 0000000..aa1b0e5 --- /dev/null +++ b/order-history-service/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/order-history-service/tsconfig.json b/order-history-service/tsconfig.json new file mode 100644 index 0000000..60bce4b --- /dev/null +++ b/order-history-service/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "strictPropertyInitialization": false, + "types": ["vite/client"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/order-history-service/tsconfig.spec.json b/order-history-service/tsconfig.spec.json new file mode 100644 index 0000000..bd57cb3 --- /dev/null +++ b/order-history-service/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts"] +} diff --git a/order-history-service/vite.config.ts b/order-history-service/vite.config.ts new file mode 100644 index 0000000..876a12c --- /dev/null +++ b/order-history-service/vite.config.ts @@ -0,0 +1,6 @@ +// eslint-disable-next-line @nx/enforce-module-boundaries +import { defineNodeConfig } from '../node-vite-config'; + +export default defineNodeConfig({ + root: __dirname, +}); diff --git a/order-service-api/.eslintrc.json b/order-service-api/.eslintrc.json new file mode 100644 index 0000000..4069f0d --- /dev/null +++ b/order-service-api/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/vite.config.{js,ts,mjs,mts}"] + } + ] + } + } + ] +} diff --git a/order-service-api/README.md b/order-service-api/README.md new file mode 100644 index 0000000..f5751dc --- /dev/null +++ b/order-service-api/README.md @@ -0,0 +1,11 @@ +# order-service-api + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build order-service-api` to build the library. + +## Running unit tests + +Run `nx test order-service-api` to execute the unit tests via [Vitest](https://vitest.dev/). diff --git a/order-service-api/package.json b/order-service-api/package.json new file mode 100644 index 0000000..8756005 --- /dev/null +++ b/order-service-api/package.json @@ -0,0 +1,10 @@ +{ + "name": "@ftgo/order-service-api", + "version": "0.0.1", + "dependencies": { + "tslib": "^2.3.0" + }, + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "private": true +} diff --git a/order-service-api/project.json b/order-service-api/project.json new file mode 100644 index 0000000..a71e06c --- /dev/null +++ b/order-service-api/project.json @@ -0,0 +1,26 @@ +{ + "name": "order-service-api", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "order-service-api/src", + "projectType": "library", + "tags": [], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/order-service-api", + "main": "order-service-api/src/index.ts", + "tsConfig": "order-service-api/tsconfig.lib.json", + "assets": ["order-service-api/*.md"] + } + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "reportsDirectory": "../coverage/order-service-api" + } + } + } +} diff --git a/order-service-api/src/index.ts b/order-service-api/src/index.ts new file mode 100644 index 0000000..cd1a09c --- /dev/null +++ b/order-service-api/src/index.ts @@ -0,0 +1 @@ +export * from './lib/order-service-api'; diff --git a/order-service-api/src/lib/order-service-api.spec.ts b/order-service-api/src/lib/order-service-api.spec.ts new file mode 100644 index 0000000..d3bae76 --- /dev/null +++ b/order-service-api/src/lib/order-service-api.spec.ts @@ -0,0 +1,7 @@ +import { orderServiceApi } from './order-service-api'; + +describe('orderServiceApi', () => { + it('should work', () => { + expect(orderServiceApi()).toEqual('order-service-api'); + }); +}); diff --git a/order-service-api/src/lib/order-service-api.ts b/order-service-api/src/lib/order-service-api.ts new file mode 100644 index 0000000..e956e80 --- /dev/null +++ b/order-service-api/src/lib/order-service-api.ts @@ -0,0 +1,3 @@ +export function orderServiceApi(): string { + return 'order-service-api'; +} diff --git a/order-service-api/tsconfig.json b/order-service-api/tsconfig.json new file mode 100644 index 0000000..e236e0f --- /dev/null +++ b/order-service-api/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/order-service-api/tsconfig.lib.json b/order-service-api/tsconfig.lib.json new file mode 100644 index 0000000..2fd1e3f --- /dev/null +++ b/order-service-api/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/order-service-api/tsconfig.spec.json b/order-service-api/tsconfig.spec.json new file mode 100644 index 0000000..4f7fed6 --- /dev/null +++ b/order-service-api/tsconfig.spec.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "vitest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/order-service-api/vite.config.ts b/order-service-api/vite.config.ts new file mode 100644 index 0000000..ffe775a --- /dev/null +++ b/order-service-api/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite'; + +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; + +export default defineConfig({ + root: __dirname, + cacheDir: '../node_modules/.vite/order-service-api', + + plugins: [nxViteTsPaths()], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + test: { + watch: false, + globals: true, + environment: 'node', + include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + coverage: { + reportsDirectory: '../coverage/order-service-api', + provider: 'v8', + }, + }, +}); diff --git a/order-service/.eslintrc.json b/order-service/.eslintrc.json new file mode 100644 index 0000000..1ad7cf0 --- /dev/null +++ b/order-service/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/order-service/project.json b/order-service/project.json new file mode 100644 index 0000000..113152c --- /dev/null +++ b/order-service/project.json @@ -0,0 +1,104 @@ +{ + "name": "order-service", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "ftgo", + "sourceRoot": "order-service/src", + "tags": [], + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "development", + "inputs": ["order-service"], + "options": { + "buildLibsFromSource": false, + "generatePackageJson": true, + "outputPath": "dist/order-service", + "ssr": "src/main.ts", + "emptyOutDir": true, + "outputFileName": "main.mjs" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "order-service:build", + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "order-service:build:development", + "args": ["order-service:start"], + "watch": true + }, + "production": { + "buildTarget": "order-service:build:production" + }, + "staging": { + "buildTarget": "order-service:build:staging" + } + } + }, + "container": { + "executor": "@nx-tools/nx-container:build", + "dependsOn": ["build"], + "options": { + "engine": "docker", + "push": true, + "cache-from": ["type=gha"], + "cache-to": ["type=gha,mode=max"], + "metadata": { + "images": ["ghcr.io/zapxme/order-service"], + "tags": [ + "type=schedule", + "type=ref,event=branch", + "type=ref,event=tag", + "type=ref,event=pr", + "type=sha,prefix=sha-" + ] + } + } + }, + "create-migration": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "order-service:build", + "args": [ + "migration:create", + "--migrationDir", + "order-service/src/migrations" + ], + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "order-service:build:development" + }, + "production": { + "buildTarget": "order-service:build:production" + }, + "staging": { + "buildTarget": "order-service:build:staging" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{projectRoot}/coverage"] + } + } +} diff --git a/order-service/src/assets/.gitkeep b/order-service/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/order-service/src/main.ts b/order-service/src/main.ts new file mode 100644 index 0000000..3451e9b --- /dev/null +++ b/order-service/src/main.ts @@ -0,0 +1 @@ +console.log('Hello World'); diff --git a/order-service/tsconfig.app.json b/order-service/tsconfig.app.json new file mode 100644 index 0000000..aa1b0e5 --- /dev/null +++ b/order-service/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/order-service/tsconfig.json b/order-service/tsconfig.json new file mode 100644 index 0000000..60bce4b --- /dev/null +++ b/order-service/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "strictPropertyInitialization": false, + "types": ["vite/client"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/order-service/tsconfig.spec.json b/order-service/tsconfig.spec.json new file mode 100644 index 0000000..bd57cb3 --- /dev/null +++ b/order-service/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts"] +} diff --git a/order-service/vite.config.ts b/order-service/vite.config.ts new file mode 100644 index 0000000..876a12c --- /dev/null +++ b/order-service/vite.config.ts @@ -0,0 +1,6 @@ +// eslint-disable-next-line @nx/enforce-module-boundaries +import { defineNodeConfig } from '../node-vite-config'; + +export default defineNodeConfig({ + root: __dirname, +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..da8fb2d --- /dev/null +++ b/package.json @@ -0,0 +1,57 @@ +{ + "name": "@ftgo/source", + "version": "0.0.0", + "license": "MIT", + "scripts": {}, + "private": true, + "type": "module", + "devDependencies": { + "@deepkit/type-compiler": "^1.0.1-alpha.150", + "@deepkit/vite": "^1.0.1-alpha.150", + "@nx/eslint": "19.5.7", + "@nx/eslint-plugin": "19.5.7", + "@nx/js": "19.5.7", + "@nx/node": "^19.5.7", + "@nx/vite": "^19.5.7", + "@nx/workspace": "19.5.7", + "@types/node": "~18.16.9", + "@typescript-eslint/eslint-plugin": "^7.16.0", + "@typescript-eslint/parser": "^7.16.0", + "@vitest/coverage-v8": "^1.0.4", + "@vitest/ui": "^1.3.1", + "eslint": "~8.57.0", + "eslint-config-prettier": "^9.0.0", + "nx": "19.5.7", + "prettier": "^3.3.3", + "typescript": "^5.5.4", + "vite": "^5.4.0", + "vitest": "^2.0.5" + }, + "patchedDependencies": { + "typescript@5.5.4": "patches/typescript@5.5.4.patch" + }, + "dependencies": { + "@deepkit/app": "^1.0.1-alpha.153", + "@deepkit/broker": "^1.0.1-alpha.153", + "@deepkit/bson": "^1.0.1-alpha.153", + "@deepkit/core": "^1.0.1-alpha.147", + "@deepkit/event": "^1.0.1-alpha.153", + "@deepkit/filesystem": "^1.0.1-alpha.147", + "@deepkit/framework": "^1.0.1-alpha.153", + "@deepkit/injector": "^1.0.1-alpha.153", + "@deepkit/orm": "^1.0.1-alpha.153", + "@deepkit/postgres": "^1.0.1-alpha.153", + "@deepkit/sql": "^1.0.1-alpha.153", + "@deepkit/type": "^1.0.1-alpha.153", + "deepkit-restate": "^0.0.27", + "tslib": "2.6.3" + }, + "engines": { + "node": "22.6.0", + "bun": "1.1.22" + }, + "trustedDependencies": [ + "@deepkit/type-compiler", + "nx" + ] +} diff --git a/patches/typescript@5.5.4.patch b/patches/typescript@5.5.4.patch new file mode 100644 index 0000000..266dd18 --- /dev/null +++ b/patches/typescript@5.5.4.patch @@ -0,0 +1,13 @@ +diff --git a/lib/typescript.js b/lib/typescript.js +index 74ad448c62355fa6645a6624d334e1b1152695fe..532819bd9766f00e16df7417ffd46acf29b53bd7 100644 +--- a/lib/typescript.js ++++ b/lib/typescript.js +@@ -92863,7 +92863,7 @@ var visitEachChildTable = { + [183 /* TypeReference */]: function visitEachChildOfTypeReferenceNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { + return context.factory.updateTypeReferenceNode( + node, +- Debug.checkDefined(nodeVisitor(node.typeName, visitor, isEntityName)), ++ Debug.checkDefined(nodeVisitor(node.typeName, visitor, node => isTypeNode(node) || isEntityName(node))), + nodesVisitor(node.typeArguments, visitor, isTypeNode) + ); + }, diff --git a/restaurant-service-api/.eslintrc.json b/restaurant-service-api/.eslintrc.json new file mode 100644 index 0000000..4069f0d --- /dev/null +++ b/restaurant-service-api/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/vite.config.{js,ts,mjs,mts}"] + } + ] + } + } + ] +} diff --git a/restaurant-service-api/README.md b/restaurant-service-api/README.md new file mode 100644 index 0000000..bdbfa0d --- /dev/null +++ b/restaurant-service-api/README.md @@ -0,0 +1,11 @@ +# restaurant-service-api + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build restaurant-service-api` to build the library. + +## Running unit tests + +Run `nx test restaurant-service-api` to execute the unit tests via [Vitest](https://vitest.dev/). diff --git a/restaurant-service-api/package.json b/restaurant-service-api/package.json new file mode 100644 index 0000000..1006f0c --- /dev/null +++ b/restaurant-service-api/package.json @@ -0,0 +1,10 @@ +{ + "name": "@ftgo/restaurant-service-api", + "version": "0.0.1", + "dependencies": { + "tslib": "^2.3.0" + }, + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "private": true +} diff --git a/restaurant-service-api/project.json b/restaurant-service-api/project.json new file mode 100644 index 0000000..66b9a68 --- /dev/null +++ b/restaurant-service-api/project.json @@ -0,0 +1,26 @@ +{ + "name": "restaurant-service-api", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "restaurant-service-api/src", + "projectType": "library", + "tags": [], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/restaurant-service-api", + "main": "restaurant-service-api/src/index.ts", + "tsConfig": "restaurant-service-api/tsconfig.lib.json", + "assets": ["restaurant-service-api/*.md"] + } + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "reportsDirectory": "../coverage/restaurant-service-api" + } + } + } +} diff --git a/restaurant-service-api/src/index.ts b/restaurant-service-api/src/index.ts new file mode 100644 index 0000000..05f8efe --- /dev/null +++ b/restaurant-service-api/src/index.ts @@ -0,0 +1 @@ +export * from './lib/restaurant-service-api'; diff --git a/restaurant-service-api/src/lib/order-service-api.spec.ts b/restaurant-service-api/src/lib/order-service-api.spec.ts new file mode 100644 index 0000000..4a2aa7f --- /dev/null +++ b/restaurant-service-api/src/lib/order-service-api.spec.ts @@ -0,0 +1,7 @@ +import { orderServiceApi } from './restaurant-service-api'; + +describe('orderServiceApi', () => { + it('should work', () => { + expect(orderServiceApi()).toEqual('restaurant-service-api'); + }); +}); diff --git a/restaurant-service-api/src/lib/order-service-api.ts b/restaurant-service-api/src/lib/order-service-api.ts new file mode 100644 index 0000000..5f96989 --- /dev/null +++ b/restaurant-service-api/src/lib/order-service-api.ts @@ -0,0 +1,3 @@ +export function orderServiceApi(): string { + return 'restaurant-service-api'; +} diff --git a/restaurant-service-api/tsconfig.json b/restaurant-service-api/tsconfig.json new file mode 100644 index 0000000..e236e0f --- /dev/null +++ b/restaurant-service-api/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/restaurant-service-api/tsconfig.lib.json b/restaurant-service-api/tsconfig.lib.json new file mode 100644 index 0000000..2fd1e3f --- /dev/null +++ b/restaurant-service-api/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/restaurant-service-api/tsconfig.spec.json b/restaurant-service-api/tsconfig.spec.json new file mode 100644 index 0000000..4f7fed6 --- /dev/null +++ b/restaurant-service-api/tsconfig.spec.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "vitest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/restaurant-service-api/vite.config.ts b/restaurant-service-api/vite.config.ts new file mode 100644 index 0000000..e32ad9e --- /dev/null +++ b/restaurant-service-api/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite'; + +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; + +export default defineConfig({ + root: __dirname, + cacheDir: '../node_modules/.vite/restaurant-service-api', + + plugins: [nxViteTsPaths()], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + test: { + watch: false, + globals: true, + environment: 'node', + include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + coverage: { + reportsDirectory: '../coverage/restaurant-service-api', + provider: 'v8', + }, + }, +}); diff --git a/restaurant-service/.eslintrc.json b/restaurant-service/.eslintrc.json new file mode 100644 index 0000000..1ad7cf0 --- /dev/null +++ b/restaurant-service/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/restaurant-service/project.json b/restaurant-service/project.json new file mode 100644 index 0000000..29bb625 --- /dev/null +++ b/restaurant-service/project.json @@ -0,0 +1,104 @@ +{ + "name": "restaurant-service", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "ftgo", + "sourceRoot": "restaurant-service/src", + "tags": [], + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "development", + "inputs": ["restaurant-service"], + "options": { + "buildLibsFromSource": false, + "generatePackageJson": true, + "outputPath": "dist/restaurant-service", + "ssr": "src/main.ts", + "emptyOutDir": true, + "outputFileName": "main.mjs" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "restaurant-service:build", + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "restaurant-service:build:development", + "args": ["restaurant-service:start"], + "watch": true + }, + "production": { + "buildTarget": "restaurant-service:build:production" + }, + "staging": { + "buildTarget": "restaurant-service:build:staging" + } + } + }, + "container": { + "executor": "@nx-tools/nx-container:build", + "dependsOn": ["build"], + "options": { + "engine": "docker", + "push": true, + "cache-from": ["type=gha"], + "cache-to": ["type=gha,mode=max"], + "metadata": { + "images": ["ghcr.io/zapxme/restaurant-service"], + "tags": [ + "type=schedule", + "type=ref,event=branch", + "type=ref,event=tag", + "type=ref,event=pr", + "type=sha,prefix=sha-" + ] + } + } + }, + "create-migration": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "restaurant-service:build", + "args": [ + "migration:create", + "--migrationDir", + "restaurant-service/src/migrations" + ], + "watch": false + }, + "configurations": { + "development": { + "buildTarget": "restaurant-service:build:development" + }, + "production": { + "buildTarget": "restaurant-service:build:production" + }, + "staging": { + "buildTarget": "restaurant-service:build:staging" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{projectRoot}/coverage"] + } + } +} diff --git a/restaurant-service/src/assets/.gitkeep b/restaurant-service/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/restaurant-service/src/main.ts b/restaurant-service/src/main.ts new file mode 100644 index 0000000..3451e9b --- /dev/null +++ b/restaurant-service/src/main.ts @@ -0,0 +1 @@ +console.log('Hello World'); diff --git a/restaurant-service/tsconfig.app.json b/restaurant-service/tsconfig.app.json new file mode 100644 index 0000000..aa1b0e5 --- /dev/null +++ b/restaurant-service/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/restaurant-service/tsconfig.json b/restaurant-service/tsconfig.json new file mode 100644 index 0000000..60bce4b --- /dev/null +++ b/restaurant-service/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "strictPropertyInitialization": false, + "types": ["vite/client"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/restaurant-service/tsconfig.spec.json b/restaurant-service/tsconfig.spec.json new file mode 100644 index 0000000..bd57cb3 --- /dev/null +++ b/restaurant-service/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": ["vitest/globals"] + }, + "include": ["src/**/*.ts"] +} diff --git a/restaurant-service/vite.config.ts b/restaurant-service/vite.config.ts new file mode 100644 index 0000000..876a12c --- /dev/null +++ b/restaurant-service/vite.config.ts @@ -0,0 +1,6 @@ +// eslint-disable-next-line @nx/enforce-module-boundaries +import { defineNodeConfig } from '../node-vite-config'; + +export default defineNodeConfig({ + root: __dirname, +}); diff --git a/shared/.eslintrc.json b/shared/.eslintrc.json new file mode 100644 index 0000000..4069f0d --- /dev/null +++ b/shared/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/vite.config.{js,ts,mjs,mts}"] + } + ] + } + } + ] +} diff --git a/shared/README.md b/shared/README.md new file mode 100644 index 0000000..1cf1174 --- /dev/null +++ b/shared/README.md @@ -0,0 +1,11 @@ +# shared + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build shared` to build the library. + +## Running unit tests + +Run `nx test shared` to execute the unit tests via [Vitest](https://vitest.dev/). diff --git a/shared/package.json b/shared/package.json new file mode 100644 index 0000000..3aea556 --- /dev/null +++ b/shared/package.json @@ -0,0 +1,10 @@ +{ + "name": "@ftgo/shared", + "version": "0.0.1", + "dependencies": { + "tslib": "^2.3.0" + }, + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "private": true +} diff --git a/shared/project.json b/shared/project.json new file mode 100644 index 0000000..19ec7e3 --- /dev/null +++ b/shared/project.json @@ -0,0 +1,26 @@ +{ + "name": "shared", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "shared/src", + "projectType": "library", + "tags": [], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/shared", + "main": "shared/src/index.ts", + "tsConfig": "shared/tsconfig.lib.json", + "assets": ["shared/*.md"] + } + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "reportsDirectory": "../coverage/shared" + } + } + } +} diff --git a/shared/src/index.ts b/shared/src/index.ts new file mode 100644 index 0000000..a14dbcb --- /dev/null +++ b/shared/src/index.ts @@ -0,0 +1,3 @@ +export * from './lib/repository'; +export * from './lib/config'; +export * from './lib/types'; diff --git a/shared/src/lib/config.ts b/shared/src/lib/config.ts new file mode 100644 index 0000000..af8c0c6 --- /dev/null +++ b/shared/src/lib/config.ts @@ -0,0 +1,16 @@ +import { integer } from '@deepkit/type'; + +export class DatabaseConfig { + readonly host: string; + readonly name: string; + readonly user: string; + readonly password: string; + readonly port: integer; +} + +export class RestateConfig { + readonly host: string; + readonly port: string; + readonly adminPort: integer; + readonly ingressPort: integer; +} diff --git a/shared/src/lib/repository.ts b/shared/src/lib/repository.ts new file mode 100644 index 0000000..b2042f6 --- /dev/null +++ b/shared/src/lib/repository.ts @@ -0,0 +1,36 @@ +import {ClassType} from '@deepkit/core'; +import {ChangesInterface, DeepPartial, JSONPartial,} from '@deepkit/type'; +import {Database, DatabaseQueryModel, DeleteResult, OrmEntity, PatchResult,} from '@deepkit/orm'; + +export function Repository(entity: ClassType & { create(data: JSONPartial): T; }) { + return class BaseRepository { + constructor(readonly database: Database) {} + + async findOne(filter: DatabaseQueryModel['filter']): Promise { + return await this.database.query(entity).filter(filter).findOne(); + } + + async deleteOne( + filter: DatabaseQueryModel['filter'], + ): Promise> { + return await this.database.query(entity).filter(filter).deleteOne(); + } + + async find(filter: DatabaseQueryModel['filter']): Promise { + return await this.database.query(entity).filter(filter).find(); + } + + async update( + filter: DatabaseQueryModel['filter'], + changes: ChangesInterface | DeepPartial, + ): Promise> { + return await this.database.query(entity).filter(filter).patchOne(changes); + } + + async create(data: JSONPartial): Promise { + const et = entity.create(data); + await this.database.persist(et); + return et; + } + }; +} diff --git a/shared/src/lib/types.ts b/shared/src/lib/types.ts new file mode 100644 index 0000000..99f7132 --- /dev/null +++ b/shared/src/lib/types.ts @@ -0,0 +1,4 @@ +export interface PersonName { + readonly firstName: string; + readonly lastName: string; +} diff --git a/shared/tsconfig.json b/shared/tsconfig.json new file mode 100644 index 0000000..e236e0f --- /dev/null +++ b/shared/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/shared/tsconfig.lib.json b/shared/tsconfig.lib.json new file mode 100644 index 0000000..2fd1e3f --- /dev/null +++ b/shared/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/shared/tsconfig.spec.json b/shared/tsconfig.spec.json new file mode 100644 index 0000000..4f7fed6 --- /dev/null +++ b/shared/tsconfig.spec.json @@ -0,0 +1,26 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "vitest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/shared/vite.config.ts b/shared/vite.config.ts new file mode 100644 index 0000000..e145ba2 --- /dev/null +++ b/shared/vite.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vite'; + +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; + +export default defineConfig({ + root: __dirname, + cacheDir: '../node_modules/.vite/shared', + + plugins: [nxViteTsPaths()], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + test: { + watch: false, + globals: true, + environment: 'node', + include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + coverage: { + reportsDirectory: '../coverage/shared', + provider: 'v8', + }, + }, +}); diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..0ff9ceb --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,55 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "rootDir": ".", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "strictPropertyInitialization": false, + "emitDecoratorMetadata": true, + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": false, + "noImplicitReturns": true, + "preserveSymlinks": true, + "noFallthroughCasesInSwitch": true, + "strict": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "esnext", + "module": "esnext", + "lib": [ + "esnext", + "dom" + ], + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "baseUrl": ".", + "types": [ + "node" + ], + "paths": { + "@ftgo/consumer-service-api": [ + "consumer-service-api/src/index.ts" + ], + "@ftgo/delivery-service-api": [ + "delivery-service-api/src/index.ts" + ], + "@ftgo/kitchen-service-api": [ + "kitchen-service-api/src/index.ts" + ], + "@ftgo/order-service-api": [ + "order-service-api/src/index.ts" + ], + "@ftgo/restaurant-service-api": [ + "restaurant-service-api/src/index.ts" + ], + "@ftgo/shared": [ + "shared/src/index.ts" + ] + } + }, + "exclude": ["node_modules", "tmp"] +} diff --git a/vitest.workspace.ts b/vitest.workspace.ts new file mode 100644 index 0000000..3c983a2 --- /dev/null +++ b/vitest.workspace.ts @@ -0,0 +1 @@ +export default ['**/*/vite.config.ts', '**/*/vitest.config.ts'];